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();
def userDefinedTokenization = props['userDefinedTokenization'].trim();
def startTokenDelimiter = props['startTokenDelimiter'].trim();
def endTokenDelimiter = props['endTokenDelimiter'].trim();

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

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

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

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

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

// 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, startTokenDelimiter, endTokenDelimiter)

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

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, startTokenDelimiter + "websphere.server" + endTokenDelimiter)
}

if (clusterName != ""){
  outputFileContents = outputFileContents.replace(clusterName, startTokenDelimiter + "websphere.cluster" + endTokenDelimiter)
}

if (nodeName != ""){
  outputFileContents = outputFileContents.replace(nodeName, startTokenDelimiter + "websphere.node" + endTokenDelimiter)
}

if (cellName != ""){
  outputFileContents = outputFileContents.replace(cellName, startTokenDelimiter + "websphere.cell" + endTokenDelimiter)
}

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')

// tokenize user defined values
outputFile = new File(outputFileString)
doUserDefinedTokenization(outputFile, userDefinedTokenization)

// 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 startTokenDelimiter, String endTokenDelimiter) {
  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.key == "websphere.variablemap.entries") {
          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
              println "Tokenizing profile name " + profileName + " in " + file.getName()
              e.value = e.value.replace(profileName, startTokenDelimiter + "websphere.node.profilename" + endTokenDelimiter)
              foundProfileName = true
            }
          }
        }
      }
    }
  }

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

// method to handle user defined tokenization
void doUserDefinedTokenization(File file, String userDefinedTokenization) {
  String fileContents = file.getText('UTF-8')
  lines = userDefinedTokenization.split('\n')
  for (line in lines) {
    if (line.indexOf("->") >= 0) {
      oldStart = 0
      oldEnd = line.indexOf("->")
      oldValue = line.substring(oldStart, oldEnd)
      newStart = line.indexOf("->") + 2
      newEnd = line.length();
      newValue = line.substring(newStart, newEnd)
      println "Replacing " + oldValue + " with " + newValue
      fileContents = fileContents.replace(oldValue, newValue)
    }
  }
  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')
  }
}
