package usda.weru.weps.serverControl;

import java.nio.file.Paths;
import java.util.EnumMap;
import java.util.StringTokenizer;
import java.util.Vector;
import usda.weru.util.ConfigData;

/**
 *
 * @author mhaas
 */
public final class ServerControlData {
    
    public final static String cdKeyInterpBase = "CD-SC-windgen-interpolate";
    public final static String cdKeyInterpPrepareDataBase = "CD-SC-windgen-interpolate-prepareData";
    public final static String cdKeyInterpGendataBase = "CD-SC-windgen-interpolate-genData";
    public final static String cdKeyWindgenBase = "CD-SC-windgen";
    public final static String cdKeyCligenBase = "CD-SC-cligen";
    public final static String cdKeyWepsBase = "CD-SC-weps";
    public final static String cdKeySciCombinedBase = "CD-SC-csipCombined";
    public final static String cdKeyDataHandlerBase = "CD-SC-dataHandler";
    public final static String cdKeyWebStartBase = "CD-SC-WS";

    public final static String cdKeyAddExec = "-execOnServer";
    public final static String cdKeyAddEndpoint = "-endpoint";
    public final static String cdKeyAddLocalJetty = "-runLocalJetty";
    public final static String cdKeyAddExeFileRef = "-exeFileRef";
    public final static String cdKeyAddJnlpUrlRef = "-jnlpUrlRef";
    public final static String cdKeyAddExeFilename = "-exeFilename";
    public final static String cdKeyAddInFiles = "-inFiles";
    public final static String cdKeyAddOutFiles = "-outFiles";
    public final static String cdKeyAddIfInterp = "-ifInterp";
    public final static String cdKeyAddInvocationBase = "-InvocationUrlBase";
    public final static String cdKeyAddInvocationBaseInstall = "-InvocationUrlBaseInstall";
    public final static String cdKeyAddInstallerEndpoint = "-InstallerEndpoint";
    public final static String cdKeyAddUpdateFreq = "-UpdateFreq";
    public final static String cdKeyAddUpdateLast = "-UpdateLast";
    
    public final static String wepsWsDataDirName = "Data";
    
    private final String cdKeyCloudProgressLen = "CD-SC-cloudProgressLen";
    
    public static boolean dataExecLocalSet (ConfigData cd) {
        return true;
    }
    
    public static boolean anyCsipSciExecLocalSet (ConfigData cd) {
        boolean ret = false;
        
        ret = checkLocalExecSet (cd, cdKeyInterpBase, ret);
        ret = checkLocalExecSet (cd, cdKeyInterpPrepareDataBase, ret);
        ret = checkLocalExecSet (cd, cdKeyInterpGendataBase, ret);
        ret = checkLocalExecSet (cd, cdKeyWindgenBase, ret);
        ret = checkLocalExecSet (cd, cdKeyCligenBase, ret);
        ret = checkLocalExecSet (cd, cdKeyWepsBase, ret);
        
        return ret;
    }
    
    public static boolean anyCsipDataExecLocalSet (ConfigData cd) {
        boolean ret = false;
        
        ret = checkLocalExecSet (cd, cdKeyDataHandlerBase, ret);
        
        return ret;
    }
    
    private static boolean checkLocalExecSet (ConfigData cd, String keyBase, boolean ret) {
        String tStr = cd.getData(keyBase + cdKeyAddExec);
        //String tStr = cd.getData(keyBase + cdKeyAddLocalJetty);
        if (tStr != null)
            if (tStr.contentEquals("1"))
                if (cd.getData(keyBase + cdKeyAddEndpoint).contains("localhost")) {
                    //System.err.println("CSIP endpoint being checked="+cd.getData(keyBase + cdKeyAddEndpoint));
                    ret = true;
                }
        return ret;
    }
    
        
    public enum cdKeyIdx {
        Interpolate,
        InterpolatePrepareData,
        InterpolateGenData,
        Windgen,
        Cligen,
        Weps
    };
    
    public final EnumMap<cdKeyIdx,String> cdKeyMap;        
    private final ConfigData configData;
    private boolean interpolateMode;
    

    public ServerControlData() {
        configData = ConfigData.getDefault();
        interpolateMode = false;

        cdKeyMap = new EnumMap<>(cdKeyIdx.class);
        cdKeyMap.put(cdKeyIdx.Interpolate, cdKeyInterpBase);
        cdKeyMap.put(cdKeyIdx.InterpolatePrepareData, cdKeyInterpPrepareDataBase);
        cdKeyMap.put(cdKeyIdx.InterpolateGenData, cdKeyInterpGendataBase);
        cdKeyMap.put(cdKeyIdx.Windgen, cdKeyWindgenBase);
        cdKeyMap.put(cdKeyIdx.Cligen, cdKeyCligenBase);
        cdKeyMap.put(cdKeyIdx.Weps, cdKeyWepsBase);
        
        init();
    }
    
    public void init () {

        updateFileName (cdKeyMap.get(cdKeyIdx.Interpolate));
        updateFileName (cdKeyMap.get(cdKeyIdx.InterpolatePrepareData));
        updateFileName (cdKeyMap.get(cdKeyIdx.InterpolateGenData));
        updateFileName (cdKeyMap.get(cdKeyIdx.Windgen));
        updateFileName (cdKeyMap.get(cdKeyIdx.Cligen));
        updateFileName (cdKeyMap.get(cdKeyIdx.Weps));
    }
    
    public void setInterpolateMode () {
        interpolateMode = true;
    }
    
    private void updateFileName(String cdKey) {
        String tStr;
        String fName;
        
        // look up the exe filename in its original location in the ConfigData,
        // (we store a reference to that ConfigData item)
        // and copy only the filename into the appropriate ServerControl item
        tStr = configData.getData(cdKey+cdKeyAddExeFileRef);
        if (tStr != null) {
            fName = configData.getData(tStr);
            if (fName != null) {
                tStr = Paths.get(fName).getFileName().toString();
                if (tStr != null) {
                    configData.setData(cdKey+cdKeyAddExeFilename,tStr);
                }
            }
        }
    }
    
    public boolean chkExecOnServerSet (String exeRef) {
        return (configData.getData(findCdBaseFromExe(exeRef)+cdKeyAddExec).contains("1"));
    }
    
    public String[] getInputFiles (String exeRef) {
        String cdBase = findCdBaseFromExe(exeRef);
        if (interpolateMode && configData.getData(cdBase+cdKeyAddIfInterp+cdKeyAddInFiles) != null) {
            return (getFiles(cdBase+cdKeyAddIfInterp+cdKeyAddInFiles));
        }
        return (getFiles(cdBase+cdKeyAddInFiles));
    }
    
    public String[] getOutputFiles (String exeRef) {
        String cdBase = findCdBaseFromExe(exeRef);
        if (interpolateMode && configData.getData(cdBase+cdKeyAddIfInterp+cdKeyAddOutFiles) != null) {
            return (getFiles(cdBase+cdKeyAddIfInterp+cdKeyAddOutFiles));
        }
        return (getFiles(cdBase+cdKeyAddOutFiles));
    }
    
    public String getEndpoint (String exeRef) {
        return (configData.getData(findCdBaseFromExe(exeRef)+cdKeyAddEndpoint));
    }

    
    public String findCdBaseFromExe (String exeRef) {
        String tStr;
        
        tStr = makeExeKey(exeRef);
        for (String keyStr : cdKeyMap.values()) {
            if (configData.getData(keyStr+cdKeyAddExeFilename).contains(tStr)) {
                return (keyStr);
            }
        }
        return(null);
    }

    
    private String makeExeKey (String exeRef) {
        String tStr;
        // MakeInterpolatedStation adds extra quotes around path, check for and strip
        tStr = exeRef.replace('\"', ' ').trim();
        tStr = Paths.get(tStr).getFileName().toString();
        return (tStr);
    }
    

    private String[] getFiles (String sdKey) {
        Vector<String> retFiles = new Vector<String>();
        String filesStr;
        StringTokenizer st;
        
        filesStr = configData.getData(sdKey);
        st = new StringTokenizer(filesStr, " :,;\n");

        while (st.hasMoreTokens()) {
            String token = st.nextToken();
            retFiles.add(token);
        }
        String[]t = null;
        t = retFiles.toArray(new String[0]);
        return(t);
    }
    
   
    public void modifyForInterpolate (String exeRef, String inFiles[]) {
        String tStr;
        String files;
        String interpOut;

        // Remove the input files for this command and replace with the new ones
        // All other filenames are consistent run by run.  
        //    These filenames, however, are based on the actual processed data
        //    and therefore their names change from run to run.
        tStr = "";
        for (String file : inFiles) {
            tStr = tStr + file + ",";
        }
        configData.setData(findCdBaseFromExe(exeRef)+cdKeyAddInFiles,tStr);
    }
    
    
    public int getProgressLen() {
        return (Integer.valueOf( configData.getData(cdKeyCloudProgressLen)) );
    }
       
}
