#Purpose: To run COMDYN program through web.exe 

#Modules
from datetime import datetime
import selenium
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common import keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.options import Options
import pandas as pd
import numpy as np
import psutil
from joblib import Parallel, delayed
import os

#Getting working directory path
varwd = os.getcwd()

#Bringing in BBS route data
rData0 = pd.read_csv(os.path.join(varwd, "comdynInput.csv"))

#Getting records for routes that already were run
Direc = "Output"
files = os.listdir(os.path.join(varwd,Direc))
files.remove('FailedRecords.txt') #Removing file that kept failed records
files = [f.replace(".txt","").split("_") for f in files] #Splitting to rteno, iYear, and jYear

#Creating dataframe to eliminate those records already
#run
filterDF = pd.DataFrame(files, columns=['rteno','iYear','jYear'])
filterDF["fColumn"]= 1
filterDF['rteno'] = filterDF['rteno'].astype('int64')
filterDF['iYear'] = filterDF['iYear'].astype('int64')
filterDF['jYear'] = filterDF['jYear'].astype('int64')

#Merging to eliminate records already run
mergedDF = pd.merge(rData0, filterDF, on=['rteno','iYear','jYear'], how='outer')
rData0 = mergedDF[mergedDF['fColumn'].isnull()].drop(columns=['fColumn'])

#Writing output to temporary file
rData0.to_csv(os.path.join(varwd,"TempcomdynInput.csv"),index=False)

#Getting unique route identifiers
rID = rData0[["rteno"]].iloc[:,0].unique()

#Defining function to get COMDYN estimates
def COMDYN(rte):

    #COMDYN website
    u="https://www.mbr-pwrc.usgs.gov/software/comdyn4.html"

    #Bringing in BBS route data
    rData = pd.read_csv(os.path.join(varwd,"TempcomdynInput.csv"))
        
    #Getting unique combination of years for each route
    rdataSub0 = rData[(rData.rteno==rte)][["iYear","jYear"]].drop_duplicates()
    
    for it in list(range(len(rdataSub0))):

        try: 

            #Getting years
            iY = int(rdataSub0[["iYear"]].iloc[it])

            iJ = int(rdataSub0[["jYear"]].iloc[it])

            print(rte)
            print(iY)
            print(iJ)

            #Getting subset of data corresponding
            #to route
            rdataSub = rData[(rData.rteno==rte)&(rData.iYear==iY)&(rData.jYear==iJ)]
            rdataSub = rdataSub[["i1","i2","i3","i4","i5"]]

            if len(rdataSub)==8:

                #Setting up web driver
                #instance of Options class allows
                #us to configure Headless Chrome
                options = Options()
                #this parameter tells Chrome that
                #it should be run without UI (Headless)
                options.add_argument("--headless=new")
                driver = webdriver.Chrome(options=options)

                #Creating action chain
                actions = ActionChains(driver)

                #Launching website
                driver.get(u)
                driver.implicitly_wait(1)

                #To identify table columns
                c = driver.find_elements(By.XPATH,"//*[@id='myTable']/tbody/tr[3]/td")
                driver.implicitly_wait(1)

                #To get column count with len method
                cc = len(c)

                #Dimensions of table
                dRow = list(range(8))
                dCol = list(range(5))

                #Indices for populating table
                cRow = [1,3,7,5,2,4,8,6]
                cCol = list(range(2,(cc+1)))

                for i in dRow:
                    # to traverse through the table column 
                    for j in dCol:
                        cell = driver.find_element(By.XPATH,"//*[@id='myTable']/tbody/tr["+str(cRow[i])+"]/td["+str(cCol[j])+"]")
                        driver.implicitly_wait(1)
                        iValue = rdataSub.iloc[i,j]
                        actions.move_to_element(cell).double_click().click_and_hold().send_keys(Keys.CLEAR).send_keys(str(iValue)).perform()
                        driver.implicitly_wait(2)

                #Click on button to run the program
                button = driver.find_element(By.XPATH, "/html/body/button[1]")
                button.click()
                driver.implicitly_wait(2)

                #Getting output
                out = driver.find_element(By.ID,"out").text
                driver.implicitly_wait(2)

                f = open(varwd+'\\Output\\'+str(rte)+"_"+str(iY)+"_"+str(iJ)+'.txt', 'w',encoding="utf-8")
                f.write(str(out))
                f.close()
                
                driver.close()

        except:

            #Creating file to store output
            oFile = open(varwd+'\\Output\\'+'FailedRecords.txt', 'w')
            
            #Getting years
            iY = int(rdataSub0[["iYear"]].iloc[it])
            iJ = int(rdataSub0[["jYear"]].iloc[it])

            #Creating line to write
            out = [str(rte)," ",str(iY)," ",str(iJ),"\n"]

            #Writing line out
            oFile.writelines(out)
            oFile.close()

for rte in rID:
    
    print("route: ",rte)
    
    COMDYN(rte)
