import java.io.File;

import groovy.json.JsonSlurper
import groovy.json.JsonBuilder
import groovy.io.FileType

import com.urbancode.air.AirPluginTool;

def apTool = new AirPluginTool(this.args[0], this.args[1]);
def props = apTool.getStepProperties();


def newConfigFile = props['newConfigFile'].trim();


File file = new File(newConfigFile);
if (file.isDirectory()) {
    throw new Exception("Directory exists in the way");
}
if (file.isFile()) {
   throw new Exception("The specified configuration file already exists: " + file.getAbsoluteFile());;
}
else {
    def handledPaths = [];
    def extractedResources = [];
    serverEntryDeployedApplicationsAdditionalProperties = "";
    variableMapEntriesAdditionalProperties = "";
    trustedAuthenticationRealmAdditionalProperties = "";
    File dir = new File(".");
    dir.eachFileRecurse { curfile ->
        if (curfile.getName().endsWith(".json") && !curfile.getName().equals(file.getName())) {
            println "Processing file " + curfile.getName();
            String fileContents = curfile.getText('UTF-8')
            // we expect the fileContents to be in brackets
            fileContents = fileContents.trim();
            if (fileContents.substring(0, 1) != "[") {
              fileContents = "[" + fileContents + "]"
            }
            def list = new JsonSlurper().parseText(fileContents)
            list.each {
              if (!handledPaths.contains(it.path)) {
                  extractedResources.push(it);
                  handledPaths.push(it.path);
              }
              else {
                handledMergeableProperty = false;
                // check to see if the resource type is one we need to handle
                // if it is, save the value off to the side
                if (it.roleName == "WebSphereServerEntry") {
                  // get the role properties
                  if(it.keySet().contains( 'roleProperties' )) {
                    for (e in it.roleProperties) {
                      if (e.key == "websphere.serverentry.deployedapplications") {
                        serverEntryDeployedApplicationsAdditionalProperties = serverEntryDeployedApplicationsAdditionalProperties + "\n" + e.value
                        handledMergeableProperty = true;
                      }
                    }
                  }
                }
                else if (it.roleName == "WebSphereVariableMap") {
                  // get the role properties
                  if(it.keySet().contains( 'roleProperties' )) {
                    for (e in it.roleProperties) {
                      if (e.key == "websphere.variablemap.entries") {
                        variableMapEntriesAdditionalProperties = variableMapEntriesAdditionalProperties + "\n" + e.value
                        handledMergeableProperty = true;
                      }
                    }
                  }
                }
                else if (it.roleName == "WebSphereTrustedAuthenticationRealm") {
                  // get the role properties
                  if(it.keySet().contains( 'roleProperties' )) {
                    for (e in it.roleProperties) {
                      if (e.key == "websphere.trustedauthenticationrealm.realmlist") {
                        trustedAuthenticationRealmAdditionalProperties = trustedAuthenticationRealmAdditionalProperties + "|" + e.value
                        handledMergeableProperty = true;
                      }
                    }
                  }
                }
                if (!handledMergeableProperty) {
                  println "The entry from file " + curfile.getName() + " with the following path will not be added to " + file.getName() + " because it has already been added: " + it.path;
                }
              }
            }
        }
    }
    // we now have gone through all the files and built a new list of json entries with no duplicates
    // next, let's see if we need to do any role property merging
    if (serverEntryDeployedApplicationsAdditionalProperties != "") {
      extractedResources = mergeRoleProperties(extractedResources, "WebSphereServerEntry", "websphere.serverentry.deployedapplications", serverEntryDeployedApplicationsAdditionalProperties);
    }
    if (variableMapEntriesAdditionalProperties != "") {
      extractedResources = mergeRoleProperties(extractedResources, "WebSphereVariableMap", "websphere.variablemap.entries", variableMapEntriesAdditionalProperties);
    }
    if (trustedAuthenticationRealmAdditionalProperties != "") {
      extractedResources = mergeRoleProperties(extractedResources, "WebSphereTrustedAuthenticationRealm", "websphere.trustedauthenticationrealm.realmlist", trustedAuthenticationRealmAdditionalProperties);
    }

    // create output file dir if needed
    newConfigFileDir = new File(file.getAbsoluteFile().getParent());
    if (!newConfigFileDir.exists()) {
      newConfigFileDir.mkdirs()
    }
    // write the new file
    newFileContents = new JsonBuilder(extractedResources).toPrettyString()
    new File(newConfigFile).write(newFileContents, 'UTF-8');

    //Fix double quotes
    newConfigJson = new File(newConfigFile);
    fixDoubleQuotes(newConfigJson);
}

// method to merge role properties
List mergeRoleProperties(List extractedResources, String rolename, String rolePropertyName, String valueToAdd) {
  extractedResources.each{
    if (it.roleName == rolename) {
      if(it.keySet().contains( 'roleProperties' )) {
        for (e in it.roleProperties) {
          if (e.key == rolePropertyName) {
            oldValue = e.value;
            e.value = oldValue + valueToAdd;
            println "Merging " + rolePropertyName + " value by adding " + valueToAdd + " to " + oldValue;
          }
        }
      }
    }
  }
  return extractedResources;
}

// method to fix "" saving as "\"\""
void fixDoubleQuotes(File file) {
  String fileContents = file.getText('UTF-8')
  fileContents = fileContents.replace("\"\\\"\\\"\"", "\"\"")
  file.delete()
  if (file.getParent() != null)
    new File(file.getParent()+File.separator+file.getName()).write(fileContents, 'UTF-8')
  else
    new File(file.getName()).write(fileContents, 'UTF-8')
}
