package usda.weru.remoteDataAccess.csip.crlmod;

import java.io.File;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import usda.weru.remoteDataAccess.exceptions.RdaConnectException;
import usda.weru.util.ConfigData;
import usda.weru.util.wepsFileChooser2.WepsFileTypes2;

/**
 *
 * @author mhaas
 */
public class CsipIfCrLmodMan extends CsipInterfaceCrLmod {
    
    public CsipIfCrLmodMan () {
        
    }
    
    
    @Override
    protected void addParmsCatalog (JSONObject modelParms) throws JSONException {
        JSONArray jsonParmsArr = modelParms.getJSONArray("parameter");

        jsonParmsArr.put(new JSONObject().put("name","names_only").put("value", "true") );
        jsonParmsArr.put(new JSONObject().put("name","limit").put("value", "all") );
    }
    
    
    @Override
    public ArrayList<String> callCsipCatalog () throws RdaConnectException {
        ArrayList<String>  ret = new ArrayList<>();
        JSONObject modelParms;
        JSONObject modelResult;
        
        try {
            modelParms = newCsipJson();
            addParmsCatalog(modelParms);
            modelResult = doCsipPost(ConfigData.getDefault().getData("CD-WS-csip-crlmod-man-endpoint"), modelParms);
            ret = parseResultCatalog(modelResult);
        } catch (Exception ex) {
            Logger.getLogger(this.getClass().getName()).log(Level.INFO, ex.getMessage());
            throw (new RdaConnectException("Unable to connect to CSIP Lmod service", ex, this.interfaceName));
        }
        // LMOD service does not include the file extension.
        // Add it so that we match the rest of Weps.
        for (int i = 0; i < ret.size(); i++) {
            ret.set(i, ret.get(i) + WepsFileTypes2.Management.getExtension());
        }

        return ret;
    }
        
    @Override
    protected ArrayList<String> parseResultCatalog (JSONObject modelResult) throws JSONException{
        ArrayList<String> lines = new ArrayList<>();
        JSONArray names;
        JSONObject resultObject;
        
        try {
            resultObject = modelResult.getJSONArray("result").getJSONObject(0);

            JSONArray rots = resultObject.getJSONObject("value").getJSONArray("rotations");
            int rotsCount = rots.length();

            for (int j=0; j<rotsCount; j++) {
                JSONObject manObject = rots.getJSONObject(j).getJSONArray("managements").getJSONObject(0);
                String s = manObject.getString("path");

                // use backslash at this point, it is what crLmod returns.
                // code downstream expects backslash
                s += "\\" + manObject.getString("name");
                lines.add(s);
            }
        } catch (JSONException ex) {
            Logger.getLogger(this.getClass().getName()).log(Level.INFO, ex.getMessage());
        }
        
        return lines;
    }
    
    @Override
    public File callCsipGetRecord (String name, String parentPath) throws RdaConnectException {
        String nameSave = name;
        // LMOD service does not include the file extension.
        // Remove it when calling LMOD and then add it back.
        name = name.replace(WepsFileTypes2.Management.getExtension(), "");
        
        String destUrl = ConfigData.getDefault().getData("CD-WS-csip-crlmod-man-endpoint");
        System.out.println("destUrl: " + destUrl);
        boolean stripName = !destUrl.contains("management/1.1");
        
        File lmodFile = callGetRecordLmod (destUrl, name, parentPath, stripName);
        return lmodFile;
    }
    
    @Override
    protected File parseResultRecord (JSONObject modelResults, String recordName) throws JSONException {
        return parseResultRecordLmod (modelResults, "managements", WepsFileTypes2.Management.getExtension(), recordName, "value");
    }
    
    @Override
    protected File parseResultRecordLmod (JSONObject modelResults, String serviceName, String fileExtension, String recordName, String csipDataParmName) throws JSONException {
        JSONObject resultObject;
        String resultStr;
        
        try {
            resultObject = modelResults.getJSONArray("result").getJSONObject(0);

            // Verify that only one match is returned.
            // For now fail if it occurs
            // Could add logic to attempt a match from the multiple if it occurs too often.
            JSONArray rots = resultObject.getJSONObject("value").getJSONArray("rotations");
            int rotsCount = rots.length();
            if (rotsCount > 1) {
                Logger.getLogger(this.getClass().getName()).log(Level.INFO, "multiple managments returned: ");
                for (int j=0; j<rotsCount; j++) {
                    JSONObject manObject = resultObject.getJSONObject("value").getJSONArray("rotations").getJSONObject(j).getJSONArray("managements").getJSONObject(0);
                    Logger.getLogger(this.getClass().getName()).log(Level.INFO, 
                            "returned man[" + j + "] :" +
                            manObject.getString("path") + "  :  " + 
                            manObject.getString("name"));
                }
               throw (new JSONException("Failed to convert / write LMOD data: multiple records returned from lmod"));
            }
            String dataStr = resultObject.getJSONObject("value")
                                         .getJSONArray("rotations")
                                         .getJSONObject(0)
                                         .getJSONArray("managements")
                                         .getJSONObject(0)
                                         .getString("wepsData");
            
            return writeResultRecordLmod(dataStr, fileExtension, recordName);
        } catch (JSONException ex) {
            // do logging in the caller.
            //Logger.getLogger(this.getClass().getName()).log(Level.INFO, "JSON error: " + ex.getMessage());
            //Logger.getLogger(this.getClass().getName()).log(Level.INFO, "    result: " + modelResults.toString(4));
        }
        throw (new JSONException("Failed to convert / write LMOD data: unexpected Lmod data"));
    }
}
