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 configFileString = props['configFile'].trim();
def outputFileString = props['outputFile'].trim();
def cellName = props['cellName'].trim();
def nodeName = props['nodeName'].trim();
def nodeHostName = props['nodeHostName'].trim();
def serverName = props['serverName'].trim();
def clusterName = props['clusterName'].trim();

configFile = new File(configFileString)
String configFileContents = configFile.getText('UTF-8')

if (serverName != ""){
  println "Templatizing the server name..."
  configFileContents = configFileContents.replace("/Servers/" + serverName + "/", "/Servers/@websphere.server@/")
  configFileContents = configFileContents.replace("(server):" + serverName, "(server):@websphere.server@")
}

if (clusterName != ""){
  println "Templatizing the cluster name..."
  configFileContents = configFileContents.replace("/ServerClusters/" + clusterName + "/", "/ServerClusters/@websphere.cluster@/")
  configFileContents = configFileContents.replace("(cluster):" + clusterName, "(cluster):@websphere.cluster@")
}

if (nodeName != ""){
  println "Templatizing the node name..."
  configFileContents = configFileContents.replace("/Nodes/" + nodeName + "/Servers/", "/Nodes/@websphere.node@/Servers/")
  configFileContents = configFileContents.replace("(node):" + nodeName, "(node):@websphere.node@")
}

if (cellName != ""){
  println "Templatizing the cell name..."
  configFileContents = configFileContents.replace("/" + cellName + "/", "/@websphere.cell@/")
  configFileContents = configFileContents.replace("(cell):" + cellName, "(cell):@websphere.cell@")
}

// create output file dir if needed
outputFile = new File(outputFileString)
outputFileDir = new File(outputFile.getParent())
if (!outputFileDir.exists()) {
  outputFileDir.mkdirs()
}
// delete the output file if it already exists
if (outputFile.exists()) {
  outputFile.delete()
}

// write the results to the outputFile
new File(outputFile.getParent()+File.separator+outputFile.getName()).write(configFileContents, 'UTF-8')

// find and tokenize the profile name, if there is one.
outputFile = new File(outputFileString)
tokenizeProfileName(outputFile)

// find and tokenize the node host name
outputFile = new File(outputFileString)
if (nodeHostName != ""){
  println "Templatizing the node host name..."
  tokenizeRolePropertyValues(outputFile, nodeHostName, "@websphere.node.hostname@")
}

outputFile = new File(outputFileString)
String outputFileContents = outputFile.getText('UTF-8')

// just to be safe, tokenize anything we may have missed
if (serverName != ""){
  outputFileContents = outputFileContents.replace(serverName, "@websphere.server@")
}

if (clusterName != ""){
  outputFileContents = outputFileContents.replace(clusterName, "@websphere.cluster@")
}

if (nodeName != ""){
  outputFileContents = outputFileContents.replace(nodeName, "@websphere.node@")
}

if (cellName != ""){
  outputFileContents = outputFileContents.replace(cellName, "@websphere.cell@")
}

outputFile.delete()

// write the results to the outputFile
println "Creating new configuration file: " + outputFile
new File(outputFile.getParent()+File.separator+outputFile.getName()).write(outputFileContents, 'UTF-8')

// fix double quotes
outputFile = new File(outputFileString)
fixDoubleQuotes = fixDoubleQuotes(outputFile)

// remove brackets
outputFile = new File(outputFileString)
removeBracketsFromJson(outputFile)

// method to tokenize profile name
void tokenizeProfileName(File file) {
  String fileContents = file.getText('UTF-8')
  fileContents = fileContents.trim()
  firstChar = fileContents.charAt(0)
  if (firstChar != "[") {
    fileContents = "[" + fileContents + "]"
  }
  def list = new JsonSlurper().parseText(fileContents)
  foundProfileName = false

  // find the profile name, assuming it's under /profiles/
  list.each {
    if(it.keySet().contains( 'roleProperties' )) {
      for (e in it.roleProperties) {
        if (e.value in String) {
          if (e.value.contains("/profiles/")) {
            profileNameRegex = e.value =~ /\/profiles\/(.*?)(\n|\/)/;
            profileName = profileNameRegex[0][1];
            // replace the profile name with a token
            e.value = e.value.replace(profileName, "@websphere.node.profilename@")
            foundProfileName = true
          }
        }
      }
    }
  }

  if (foundProfileName) {
    println "Tokenizing profile name for " + file.getName()
    fileContents = new JsonBuilder(list).toPrettyString()
    file.delete()
    new File(file.getParent()+File.separator+file.getName()).write(fileContents, 'UTF-8')
  }
}

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

// method to remove brackets from JSON
void removeBracketsFromJson(File file) {
  String fileContents = file.getText('UTF-8')
  fileContents = fileContents.trim()
  firstChar = fileContents.charAt(0)
  if (firstChar == "[") {
    startIndex = 1
    endIndex = fileContents.length()-1
    fileContents = fileContents.substring(startIndex, endIndex)
    file.delete()
    new File(file.getParent()+File.separator+file.getName()).write(fileContents, 'UTF-8')
  }
}

// method to tokenize role properties only
void tokenizeRolePropertyValues(File file, String propertyToTokenize, String token) {
  String fileContents = file.getText('UTF-8')
  fileContents = fileContents.trim()
  firstChar = fileContents.charAt(0)
  if (firstChar != "[") {
    fileContents = "[" + fileContents + "]"
  }
  def list = new JsonSlurper().parseText(fileContents)
  found = false

  // get all of the role properties and check their values
  list.each {
    if(it.keySet().contains( 'roleProperties' )) {
      for (e in it.roleProperties) {
        if (e.value in String) {
          if (e.value.contains(propertyToTokenize)) {
            e.value = e.value.replace(propertyToTokenize, token)
            found = true
          }
        }
      }
    }
  }

  if (found) {
    println "Tokenizing value " + propertyToTokenize + " to " + token + " for file " + file.getName()
    fileContents = new JsonBuilder(list).toPrettyString()
    file.delete()
    new File(file.getParent()+File.separator+file.getName()).write(fileContents, 'UTF-8')
  }
}
