'''
Modified on June 25, 2011
@version: 0.1
Generate time series
'''
import sys
import random

if len(sys.argv) != 4:
    print 'Invalid command. Command should be command <num_nodes> <frequency> <num times>\nMake sure to have num_time/frequency is an int'
n = int(sys.argv[1])
f = int(sys.argv[2])
l = int(sys.argv[3])/f #number of samples

fStatic = 'generatedStatic_1000.txt'
fTSLibrary = 'TSLibrary.txt'
fOut = 'nodes.txt'
random.seed(123) #TODO Set seed

class Node(object):
    def __init__(self, nid, loc, lati, longi, nType, kVer, fcName, cSp, nCore, corePC, mSize, dSize, bwLim):
        self.nid = nid
        self.loc = loc
        self.lati = lati
        self.longi= longi
        self.nType = nType
        self.kVer = kVer
        self.fcName = fcName
        self.cSp = cSp
        self.nCore = nCore
        self.corePC = corePC
        self.mSize = mSize
        self.dSize = dSize
        self.bwLim = bwLim
        self.cFree = []
        self.dFree = []
        self.tx = []
        self.mFree = []
        self.rspT = []
        self.upT = []
        self.onemLd = []
        self.tAve = []
        self.drift = []
        self.fivemLd = []
        self.boot = []
        self.rx = []

class TS(object):
    def __init__(self, nCore, mSize, length):
        self.nCore = nCore
        self.mSize = mSize
        self.length = length
        self.cFree = []
        self.dFree = []
        self.tx = []
        self.mFree = []
        self.rspT = []
        self.upT = []
        self.onemLd = []
        self.tAve = []
        self.drift = []
        self.fivemLd = []
        self.boot = []
        self.rx = []

#Load static attributes
node_list = []
fdStatic = open(fStatic, 'r')
i = 0
for line in fdStatic:
    tmp = line.split()
    node_list.append(Node(i, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], \
                     tmp[7], tmp[8], tmp[9], tmp[10], tmp[11]))
#    node_list.append(Node(i, tmp[0], tmp[1], tmp[2], tmp[3]))
    i += 1
if i != n:
    print 'No of entries in ' + fStatic + ' do not match with n. n = ' + str(n) + ' number in file = ' + str(i)
    fdStatic.close()
    sys.exit(0)
fdStatic.close()
print 'Reading static attributes - Done'

#Load time series library
ts_list = {}
nCore1 = []
nCore2 = []
nCore4 = []
nCore8 = []
nCore16 = []
i = 0
fdTSLibrary = open(fTSLibrary, 'r')
for line in fdTSLibrary:
    if line[0] == '#': continue
    tmp = line.split()
    tmp_cores = int(tmp[0]) #read no of codes & put them into buckets
    if tmp_cores == 1: nCore1.append(i)
    elif tmp_cores == 2: nCore2.append(i)
    elif tmp_cores == 4: nCore4.append(i)
    elif tmp_cores == 8: nCore8.append(i)
    elif tmp_cores == 16: nCore16.append(i)
    else:
        print 'Invalid number of cores. Terminating. ' + str(tmp_cores)
        sys.exit(0)
    length = int(tmp[2])
    ts_list[i] = TS(tmp_cores, float(tmp[1]), length)
    for j in range(3, 3 + 1 * length): ts_list[i].cFree.append(tmp[j])
    for j in range(3 + 1 * length, 3 + 2 * length): ts_list[i].dFree.append(tmp[j])
    for j in range(3 + 2 * length, 3 + 3 * length): ts_list[i].tx.append(tmp[j])
    for j in range(3 + 3 * length, 3 + 4 * length): ts_list[i].mFree.append(tmp[j])
    for j in range(3 + 4 * length, 3 + 5 * length): ts_list[i].rspT.append(tmp[j])
    for j in range(3 + 5 * length, 3 + 6 * length): ts_list[i].upT.append(tmp[j])
    for j in range(3 + 6 * length, 3 + 7 * length): ts_list[i].onemLd.append(tmp[j])
    for j in range(3 + 7 * length, 3 + 8 * length): ts_list[i].tAve.append(tmp[j])
    for j in range(3 + 8 * length, 3 + 9 * length): ts_list[i].drift.append(tmp[j])
    for j in range(3 + 9 * length, 3 + 10 * length): ts_list[i].fivemLd.append(tmp[j])
    for j in range(3 + 10  * length, 3 + 11 * length): ts_list[i].boot.append(tmp[j])
    for j in range(3 + 11 * length, 3 + 12 * length): ts_list[i].rx.append(tmp[j])
    i = i + 1
fdTSLibrary.close()
print 'Reading time series library - Done'
#for i in range(len(ts_list)):
#    print ts_list[i].cFree
#sys.exit()
#generate time series for dynamic attributes
for j in range(0, n):
    rnd_list_to_use = int(float(node_list[j].nCore)) #Pick list based on cores
    if rnd_list_to_use == 1: rnd_list_len = len(nCore1)
    elif rnd_list_to_use == 2: rnd_list_len = len(nCore2)
    elif rnd_list_to_use == 4: rnd_list_len = len(nCore4)
    elif rnd_list_to_use == 8: rnd_list_len = len(nCore8)
    elif rnd_list_to_use == 16: rnd_list_len = len(nCore16)
    else: print 'Unknown NumCores ' + str(rnd_list_to_use) 
    tmp_l = l
    while (tmp_l > 0): #more needed
        rnd_ts_num = random.randint(0, rnd_list_len - 1) #pick a random number
        if rnd_list_to_use == 1: rnd_ts_id = nCore1[rnd_ts_num] #get ID
        elif rnd_list_to_use == 2: rnd_ts_id = nCore2[rnd_ts_num] 
        elif rnd_list_to_use == 4: rnd_ts_id = nCore4[rnd_ts_num] 
        elif rnd_list_to_use == 8: rnd_ts_id = nCore8[rnd_ts_num] 
        elif rnd_list_to_use == 16: rnd_ts_id = nCore16[rnd_ts_num] 
        rnd_ts_len = ts_list[rnd_ts_id].length
        len_to_copy = min(tmp_l, rnd_ts_len)
        node_list[j].cFree.extend(ts_list[rnd_ts_id].cFree[0:len_to_copy])
        node_list[j].dFree.extend(ts_list[rnd_ts_id].dFree[0:len_to_copy])
        node_list[j].tx.extend(ts_list[rnd_ts_id].tx[0:len_to_copy])
        node_list[j].mFree.extend(ts_list[rnd_ts_id].mFree[0:len_to_copy])
        node_list[j].rspT.extend(ts_list[rnd_ts_id].rspT[0:len_to_copy])
        node_list[j].upT.extend(ts_list[rnd_ts_id].upT[0:len_to_copy])
        node_list[j].onemLd.extend(ts_list[rnd_ts_id].onemLd[0:len_to_copy])
        node_list[j].tAve.extend(ts_list[rnd_ts_id].tAve[0:len_to_copy])
        node_list[j].drift.extend(ts_list[rnd_ts_id].drift[0:len_to_copy])
        node_list[j].fivemLd.extend(ts_list[rnd_ts_id].fivemLd[0:len_to_copy])
        node_list[j].boot.extend(ts_list[rnd_ts_id].boot[0:len_to_copy])
        node_list[j].rx.extend(ts_list[rnd_ts_id].rx[0:len_to_copy])

        tmp_l = tmp_l - rnd_ts_len #reduce remaining length to copy

#dump data. Let IP be same as node ID
fdOut = open(fOut, 'w')
fdOut.write('nid\ttime\tLoc\tLati\tLongi\tNType\tKVer\tFCName\tCSp\tNCore\tCorePC\tMSize\tDSize\tBWLim\
             \tCFree\tDFree\tTx\tMFree\tRspT\tUpT\t1mLd\tTAve\tDrift\t5mLd\tBoot\tRx\n')
for j in range(0, l): #for each sample
    for k in range(0, n): #for each node
        tmp_str = str(node_list[k].nid) + '\t' + str(float(j * f)) + '\t' + node_list[k].loc + '\t'\
                  + node_list[k].lati + '\t' + node_list[k].longi + '\t' +  node_list[k].nType + '\t'\
                  + node_list[k].kVer + '\t' + node_list[k].fcName + '\t'\
                  + node_list[k].cSp + '\t' + node_list[k].nCore + '\t' +  node_list[k].corePC + '\t'\
                  + node_list[k].mSize + '\t' +  node_list[k].dSize + '\t' +  node_list[k].bwLim + '\t'\
                  + node_list[k].cFree[j] + '\t' + node_list[k].dFree[j] + '\t' + node_list[k].tx[j] + '\t'\
                  + node_list[k].mFree[j] + '\t' + node_list[k].rspT[j] + '\t' + node_list[k].upT[j] + '\t'\
                  + node_list[k].onemLd[j] + '\t' + node_list[k].tAve[j] + '\t' + node_list[k].drift[j] + '\t'\
                  + node_list[k].fivemLd[j] + '\t' + node_list[k].boot[j] + '\t' + node_list[k].rx[j] + '\n'
        fdOut.write(tmp_str)
fdOut.close()
