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.txt'
fTSLibrary = 'TSLibrary.txt'
fOut = 'nodes.txt'
random.seed(123) #TODO Set seed

class Node(object):
    def __init__(self, nid, cpu_speed, num_cores, mem_size, disk_size):
        self.nid = nid
        self.cpu_speed = cpu_speed
        self.num_cores = num_cores
        self.mem_size = mem_size
        self.disk_size = disk_size
        self.cpu_free = []
        self.one_min_load = []
        self.mem_free = []
        self.disk_free = []
        self.tx_rate = []
        self.rx_rate = []

class TS(object):
    def __init__(self, num_cores, mem_size, length):
        self.num_cores = num_cores
        self.mem_size = mem_size
        self.length = length
        self.cpu_free = []
        self.one_min_load = []
        self.mem_free = []
        self.disk_free = []
        self.tx_rate = []
        self.rx_rate = []

#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]))
    i = 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 = {}
num_cores1 = []
num_cores2 = []
num_cores4 = []
num_cores8 = []
num_cores16 = []
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: num_cores1.append(i)
    elif tmp_cores == 2: num_cores2.append(i)
    elif tmp_cores == 4: num_cores4.append(i)
    elif tmp_cores == 8: num_cores8.append(i)
    elif tmp_cores == 16: num_cores16.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 + length): ts_list[i].cpu_free.append(tmp[j])
    for j in range(3 + length, 3 + 2 * length): ts_list[i].one_min_load.append(tmp[j])
    for j in range(3 + 2 * length, 3 + 3 * length): ts_list[i].mem_free.append(tmp[j])
    for j in range(3 + 3 * length, 3 + 4 * length): ts_list[i].disk_free.append(tmp[j])
    for j in range(3 + 4 * length, 3 + 5 * length): ts_list[i].tx_rate.append(tmp[j])
    for j in range(3 + 5 * length, 3 + 6 * length): ts_list[i].rx_rate.append(tmp[j])
    i = i + 1
fdTSLibrary.close()
print 'Reading time series library - Done'
#generate time series for dynamic attributes
for j in range(0, n):
    rnd_list_to_use = int(node_list[j].num_cores) #Pick list based on cores
    if rnd_list_to_use == 1: rnd_list_len = len(num_cores1)
    elif rnd_list_to_use == 2: rnd_list_len = len(num_cores2)
    elif rnd_list_to_use == 4: rnd_list_len = len(num_cores4)
    elif rnd_list_to_use == 8: rnd_list_len = len(num_cores8)
    elif rnd_list_to_use == 16: rnd_list_len = len(num_cores16)
    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 = num_cores1[rnd_ts_num] #get ID
        elif rnd_list_to_use == 2: rnd_ts_id = num_cores2[rnd_ts_num] 
        elif rnd_list_to_use == 4: rnd_ts_id = num_cores4[rnd_ts_num] 
        elif rnd_list_to_use == 8: rnd_ts_id = num_cores8[rnd_ts_num] 
        elif rnd_list_to_use == 16: rnd_ts_id = num_cores16[rnd_ts_num] 
        rnd_ts_len = ts_list[rnd_ts_id].length
        len_to_copy = min(tmp_l, rnd_ts_len)
        node_list[j].cpu_free.extend(ts_list[rnd_ts_id].cpu_free[0:len_to_copy])
        node_list[j].one_min_load.extend(ts_list[rnd_ts_id].one_min_load[0:len_to_copy])
        node_list[j].mem_free.extend(ts_list[rnd_ts_id].mem_free[0:len_to_copy])
        node_list[j].disk_free.extend(ts_list[rnd_ts_id].disk_free[0:len_to_copy])
        node_list[j].tx_rate.extend(ts_list[rnd_ts_id].tx_rate[0:len_to_copy])
        node_list[j].rx_rate.extend(ts_list[rnd_ts_id].rx_rate[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\tIP\ttime\tCPUSpeed\tNumCores\tCPUFree\t1MinLoad\tMemSize\tMemFree\tDiskFree\tTxRate\tRxRate\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(node_list[k].nid) + '\t' + str(float(j * f)) + '\t' \
                  + node_list[k].cpu_speed + '\t' + node_list[k].num_cores + '\t' + node_list[k].cpu_free[j] \
                  + '\t' + node_list[k].one_min_load[j] + '\t' + node_list[k].mem_size + '\t' + node_list[k].mem_free[j] \
                  + '\t' + node_list[k].disk_free[j] + '\t' + node_list[k].tx_rate[j] + '\t' + node_list[k].rx_rate[j] + '\n'
        fdOut.write(tmp_str)
fdOut.close()
