/**
 * Descriptor of the Silverpeas runner tool that decorates both the Silverpeas installer and
 * configurator tool (silversetup, a standalone custom Gradle plugin).
 * The descriptor adds to the silversetup plugin the tasks to start, to stop, and to get the
 * execution status of Silverpeas.
 */

import org.silverpeas.setup.api.FileLogger
import org.silverpeas.setup.api.JBossServer
import org.silverpeas.setup.construction.SilverpeasBuilder
import static org.silverpeas.setup.construction.SilverpeasConstructionTask.SILVERPEAS_WAR
import static org.silverpeas.setup.SilverpeasSetupPlugin.JBOSS_OUTPUT_LOG

/**
 * Additional dependencies required by this tool, like some database drivers.
 */
buildscript {
  dependencies {
    classpath fileTree(dir: 'lib', include: ['*.jar'])
  }
  repositories {
    flatDir {
      dirs 'lib'
    }
  }
}

plugins {
  id 'base'
  id 'silversetup'
  id 'net.linguica.maven-settings' version '0.5'
}

description = 'Distribution of Silverpeas. Its aim is to make, to setup and to execute a Silverpeas installation'
group = 'org.silverpeas'

apply from: "${System.getenv('SILVERPEAS_HOME')}/bin/silverpeas.gradle"

/**
 * Where to find the software components that made Silverpeas. Those components will be downloaded,
 * then unpacked and finally combined into a single Web application archive ready to be deployed
 * into a JEE application server (Wildfly in our case).
 */
repositories {
  mavenLocal()
  maven {
    name 'silverpeas'
    url 'https://nexus3.silverpeas.org/repository/silverpeas'
  }
  flatDir {
    dirs 'lib'
  }
}

/**
 * Configuration properties of the silversetup Gradle plugin, required to make, to configure
 * and to install Silverpeas
 */
silversetup {
  logging {
    logDir = file("${project.silversetup.silverpeasHome.path}/log")
    defaultLevel = project.logLevel
  }
  installation {
    // mode for developers only (be caution: don't use this mode in production environment).
    developmentMode = (System.getenv('SILVERPEAS_DEV_MODE') != null ? System.getenv('SILVERPEAS_DEV_MODE').toBoolean() : false)
    if (developmentMode.get() && System.getenv('SILVERPEAS_DIST_DIR') != null) {
      distDir = file(System.getenv('SILVERPEAS_DIST_DIR'))
    }

    bundles {
      // used to construct the Silverpeas application from a descriptor of software components that
      // made up Silverpeas. See silverpeas.gradle for software configuration.
      silverpeas = project.configurations.silverpeas
      tiers = project.configurations.library
    }
  }
}

/**
 * Global project properties.
 */
project.ext {
  jbossOutputLog =  project.file("${project.silversetup.logging.logDir.path}/${JBOSS_OUTPUT_LOG}")
}

/**
 * Cleans all the artifacts produced by the build of a Silverpeas distribution.
 */
clean {
  doFirst {
    JBossServer jboss = new JBossServer(project.silversetup.jbossHome.path)
        .withStartingTimeout(project.silversetup.timeout.get())
        .redirectOutputTo(project.ext.jbossOutputLog)
    if (jboss.isStartingOrRunning()) {
      print 'WARNING: JBoss is running, stop it...'
      jboss.stop()
      println ' done'
    }
  }
  doLast {
    ant.delete(dir: project.silversetup.installation.distDir.get().path, includeemptydirs: true,
        includes: '**/*')
    ant.delete(dir: project.silversetup.installation.deploymentDir.get().path, includes: '*')
    ant.delete(dir: "${project.silversetup.silverpeasHome.path}/log", includes: 'build*.log jboss_output.log')
    ant.delete(dir: "${project.silversetup.silverpeasHome.path}/silvertrace", includeemptydirs: true)
    ant.delete(dir: "${project.silversetup.silverpeasHome.path}/migrations", includeemptydirs: true)
    ant.delete(dir: "${project.silversetup.silverpeasHome.path}/dbRepository", includeemptydirs: true)
    ant.delete(dir: "${project.silversetup.silverpeasHome.path}/resources/StringTemplates", includeemptydirs: true)
    ant.delete(dir: "${project.silversetup.silverpeasHome.path}/properties", includeemptydirs: true,
        excludes: 'org/silverpeas/authentication/**/* org/silverpeas/domains/**/* org/silverpeas/util/viewGenerator/settings/**/*')
    ant.delete(dir: "${project.silversetup.silverpeasHome.path}/xmlcomponents", includeemptydirs: true,
        excludes: 'workflows/**/*')
  }
}

/**
 * Undeploys and then deploys all the software components in the SILVERPEAS_HOME/deployments
 * directory into JBossWildfly/JBoss. Warning: the SQL driver isn't concerned by this task.
 */
task redeploy {
  description 'Redeploy all the artifacts in the SILVERPEAS_HOME/deployments folder'
  group 'Silverpeas'
  onlyIf { project.silversetup.installation.deploymentDir.get().exists() }
  JBossServer jboss = new JBossServer(project.silversetup.jbossHome.path)
      .withStartingTimeout(project.silversetup.timeout.get())
      .redirectOutputTo(project.ext.jbossOutputLog)
  doFirst {
    jboss.doWhenRunning {
      project.silversetup.installation.deploymentDir.get().listFiles().sort { a, b -> b.name <=> a.name }.each { artifact ->
        println "Undeploy ${artifact.name}..."
        jboss.undeploy(artifact.name)
      }
    }
  }
  doLast {
    try {
      project.silversetup.installation.deploymentDir.get().listFiles().sort().each { artifact ->
        println "Deploy ${artifact.name}..."
        jboss.deploy(artifact.path)
      }
    } catch (RuntimeException ex) {
      throw new GradleScriptException("Redeployment Failure", ex)
    }
  }
}

/**
 * Starts Silverpeas.
 */
task start {
  description 'Starts Silverpeas'
  group 'Silverpeas'
  doLast {
    long timeout = (project.silversetup.settings.SERVER_STARTING_TIMEOUT as Long) * 1000
    boolean serverManagementAllIP = (project.silversetup.settings.getOrDefault('SERVER_MANAGEMENT_ALL_IP', false).toBoolean())
    new JBossServer(project.silversetup.jbossHome.path)
        .setServerManagementAllIP(serverManagementAllIP)
        .withStartingTimeout(timeout)
        .redirectOutputTo(project.ext.jbossOutputLog)
        .start()
  }
}

/**
 * Starts Silverpeas in debugging mode.
 */
task debug {
  description 'Starts Silverpeas in debug mode. The debug port can be passed by the -Pport argument (default 5005)'
  group 'Silverpeas'
  doLast {
    int port = (project.ext.has('port') ? project.ext.port as int:5005)
    long timeout = (project.silversetup.settings.SERVER_STARTING_TIMEOUT as Long) * 1000
    boolean serverManagementAllIP = (project.silversetup.settings.getOrDefault('SERVER_MANAGEMENT_ALL_IP', false).toBoolean())
    new JBossServer(project.silversetup.jbossHome.path)
        .setServerManagementAllIP(serverManagementAllIP)
        .withStartingTimeout(timeout)
        .redirectOutputTo(project.ext.jbossOutputLog)
        .debug(port)
  }
}

/**
 * Stops Silverpeas.
 */
task stop {
  description 'Stops Silverpeas'
  group 'Silverpeas'
  doLast {
    new JBossServer(project.silversetup.jbossHome.path)
        .withStartingTimeout(project.silversetup.timeout.get())
        .redirectOutputTo(project.ext.jbossOutputLog)
        .stop()
  }
}

/**
 * Checks the status of the Silverpeas distribution.
 */
task status {
  description 'Checks the status of Silverpeas: is it running? is it well configured?'
  group 'Silverpeas'
  doLast {
    def jboss = new JBossServer(project.silversetup.jbossHome.path)
        .withStartingTimeout(project.silversetup.timeout.get())
    String configurationStatus = (jboss.isAlreadyConfigured() ? 'Configured: [OK]' : 'Configured: [NOK]')
    String executionStatus = (jboss.isRunning() ? 'Running:    [OK]' : 'Running:    [NOK]')
    String deploymentStatus = (jboss.isRunning() && jboss.isDeployed('silverpeas.war') ? 'Active:     [OK]' : 'Active:     [NOK]')
    println configurationStatus
    println executionStatus
    println deploymentStatus
  }
}

/**
 * Regenerates Silverpeas and redeploys it into a running
 * Wildfly/JBoss. This task is for developers and not for production. Enable only in dev mode.
 */
task reload {
  description 'Reassembles the Silverpeas war application and deploys it again while JBoss/Wildfly is running (only in dev mode)'
  group 'Silverpeas Development'
  onlyIf { silversetup.installation.developmentMode.get() }
  FileLogger log = FileLogger.getLogger('reload')
  long timeout = (project.silversetup.settings.SERVER_STARTING_TIMEOUT as Long) * 1000
  JBossServer jboss = new JBossServer(project.silversetup.jbossHome.path)
      .withStartingTimeout(timeout)
      .redirectOutputTo(project.ext.jbossOutputLog)
      .useLogger(log)
  doFirst {
    log.info "Undeploy ${SILVERPEAS_WAR}..."
    jboss.undeploy(SILVERPEAS_WAR)
    // deletes the Silverpeas distribution directory
    ant.delete(includeemptydirs: true) {
      fileset(dir: project.silversetup.installation.distDir.get().path, includes: '**/*')
    }
  }
  doLast {
    // disassembles each war that made Silverpeas
    def artifacts = configurations.silverpeas.files
    SilverpeasBuilder builder = new SilverpeasBuilder(project, log)
    builder.silverpeasHome = project.silversetup.silverpeasHome
    builder.settings = project.silversetup.settings
    builder.developmentMode = project.silversetup.installation.developmentMode.get()

    File silverpeasWar = builder.findSilverpeasCoreWarBundle(artifacts)
    builder.extractWarBundle(silverpeasWar, project.silversetup.installation.distDir.get())
    artifacts.each {
      if (it.name.endsWith('.war') && it.name != silverpeasWar.name) {
        builder.extractWarBundle(it, project.silversetup.installation.distDir.get())
      }
    }
    builder.generateSilverpeasApplication(project.silversetup.installation.distDir.get())

    try {
      log.info "Deploy ${SILVERPEAS_WAR}..."
      jboss.deploy(SILVERPEAS_WAR)
    } catch (RuntimeException ex) {
      throw new GradleScriptException("Reload Failure", ex)
    }
  }
}
