package com.hcl.devops.test.util

/*
 * Access and validate properties for the job
 */
class JobProperties {

   String serverUrl
   String offlineToken
   String teamSpace
   String projName
   String repoName
   String filepath
   String branchName
   String datasetsString
   String variablesString
   String resultPropsString
   String tagsString
   String secretsCollectionName
   String ritEnv
   String proxyHost
   String proxyPass
   String proxyPort
   String proxyUser
   String trustStorePath
   String trustStorePassword
   boolean insecure = false

   private final String outPropsFile
   private final Properties outProps = new Properties()

   public JobProperties(String inFile, String outFile) {
      outPropsFile = outFile
      File f = new File(inFile)
      if (!f.file) {
         println "The path given input properties: \"${inFile}\" does not exist"
         System.exit(1)
      }
      Properties props = new Properties()
      InputStream inputPropsStream = null
      try {
         inputPropsStream = new FileInputStream(inFile)
         props.load(inputPropsStream)
      }
      catch (IOException e) {
         throw new RuntimeException(e)
      }
      finally {
         inputPropsStream.close()
      }

      offlineToken = props['offlineToken']?.trim()
      teamSpace = props['teamspace']?.trim()
      projName = props['projName']?.trim()
      repoName = props['repoName']?.trim()
      filepath = props['filepath']?.trim()
      branchName = props['branchName']?.trim()
      datasetsString = props['datasets']
      variablesString = props['variables']
      tagsString = props['tags']
      resultPropsString = props['resultProps']
      secretsCollectionName = props['secretsCollectionName']?.trim()
      ritEnv = props['ritEnv']?.trim()
      trustStorePath = props['trustStorePath']?.trim()
      trustStorePassword = props['trustStorePassword']?.trim()

      // Networking properties
      try {
         new URL(props['serverUrl'].trim())
      } catch (MalformedURLException e) {
         println e.message
         System.exit(1)
      }
      serverUrl = props['serverUrl'].trim()
      if (serverUrl.endsWith('#insecure-skip-tls-verify')) {
         serverUrl = serverUrl.split('#')[0]
         insecure = true
      }
      if (serverUrl.endsWith('/')) {
         serverUrl = serverUrl.take(serverUrl.lastIndexOf('/'))  // Remove last character
      }
      println "[Info]  Server base URL: '${serverUrl}'"
      proxyHost = props['proxyHost']?.trim()
      if (proxyHost) {
         proxyPort = props['proxyPort'].trim()
         proxyUser = props['proxyUser'].trim()
         proxyPass = props['proxyPass']
         println "[Info]  Using Proxy Host ${proxyHost}"
         println "[Info]  Using Proxy Port ${proxyPort}"
         if (proxyUser) {
            println "[Info]  Using Proxy User ${proxyUser}"
         }
      }
      validateInput()
   }

   void validateInput() {
      if (!serverUrl) {
         println 'IBM DevOps Test Hub URL can not be blank'
         System.exit(1)
      } else if (!filepath) {
         println 'filepath can not be blank'
         System.exit(1)
      } else if (!projName) {
         println 'Project Name can not be blank'
         System.exit(1)
      } else if (!offlineToken) {
         println "No offline token provided, this can be obtained from the 'Create Token' action of the User menu in DevOps Test."
         System.exit(1)
      }
      String regex = /^https:\/\/[a-zA-Z0-9.-]+(\/[a-zA-Z0-9.-]*)?\/?(#insecure-skip-tls-verify)?$/
      if (!(serverUrl ==~ regex)) {
         println "Server URL should be of the format - https://hostname/test/ or https://hostname/ with optional '#insecure-skip-tls-verify' suffix to disable SSL checking."
         System.exit(1)
      }
      if (trustStorePath) {
         File f = new File(trustStorePath)
         if (!f.file) {
            println "The path given for the property Custom Trust Store Path: \"${trustStorePath}\" does not exist"
            System.exit(1)
         }
      }
   }

   void setOutputProperty(String name, String value) {
      this.outProps.setProperty(name, value)
      OutputStream outputPropsStream = null
      try {
         outputPropsStream = new FileOutputStream(this.outPropsFile)
         outProps.store(outputPropsStream, '')
      }
      finally {
         if (outputPropsStream != null) {
            outputPropsStream.close()
         }
      }
   }
}
