import sys
import math
import pandas as pd
import numpy as np

def main():
   if len(sys.argv) != 5:
      print('Incorrect number of parameters')
      exit(0)

   try:
      weights = list(map(float, sys.argv[2].split(',')))
      impacts = list(map(str, sys.argv[3].split(','))) 
   except:
      print('Separate weights and impacts with commas')
      exit(0)
         
   for ch in impacts:
      if ch not in ('+','-'):
         print('Incorrect impacts')
         exit(0)

   result = sys.argv[4]

   try:
      dataCSV = pd.read_csv(sys.argv[1])
   except:
      print('File not found')
      exit(0)
         
   if len(list(dataCSV.columns)) < 3:
      print('Less than 3 columns not allowed')
      exit(0)
         
   data = dataCSV.drop(['Fund Name'], axis = 1)
   (r,c) = data.shape

   if len(weights) != c or len(impacts) != c:
      print("Incorrect number of weights or impacts")
      exit(0)

   data = data.values.astype(float)
   totalW = np.sum(weights)

   rms = [0]*(c)
   for i in range(0,r):
      for j in range(0,c):
         rms[j] += (data[i][j] * data[i][j])

   for j in range(c):
      rms[j] = math.sqrt(rms[j])        
         
   for i in range(c):
      weights[i] /= totalW

   for i in range(r):
      for j in range(c):
         data[i][j] = (data[i][j] / rms[j]) * weights[j]

   maxData = np.amax(data, axis = 0) 
   minData = np.amin(data, axis = 0)

   for i in range(len(impacts)):
      if(impacts[i] == '-'):         
         temp = maxData[i]
         maxData[i] = minData[i]
         minData[i] = temp

   euclidPlus = []
   euclidMinus = []

   for i in range(r):
      sum = 0
      for j in range(c):
         sum += pow((data[i][j] - maxData[j]), 2)
      euclidPlus.append(float(pow(sum, 0.5)))

   for i in range(r):
      sum = 0
      for j in range(c):
         sum += pow((data[i][j] - minData[j]), 2)
      euclidMinus.append(float(pow(sum, 0.5)))

   performance = {}

   for i in range(r):
      performance[i + 1] = euclidMinus[i] / (euclidMinus[i] + euclidPlus[i])

   p = list(performance.values())
   pFinal = sorted(list(performance.values()), reverse = True)

   rank = {}

   for val in p:
      rank[(pFinal.index(val) + 1)] = val

   output = dataCSV
   output['Topsis Score'] = list(rank.values())
   output['Rank'] = list(rank.keys())

   res = pd.DataFrame(output)
   res.to_csv(result, index = False)

if __name__ == "__main__":
   main()