/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package openejb.tck.commands

import org.apache.commons.collections4.properties.SortedProperties
import org.apache.commons.lang.SystemUtils

/**
 * Setup the environment for running the TCK.
 *
 * @version $Revision$ $Date$
 */
class SetupCommand
    extends CommandSupport
{
    def SetupCommand(source) {
        super(source)
    }
    
    def generateTsJte() {
        def javaeeCtsHome = requireDirectory('cts.home')

        // Install the Javatest testsuite environment configuration, first filter our custom properties
        // then merge those properties with the javaee ts.jte
        ant.copy(todir: "${project.build.directory}", filtering: true, overwrite: true) {
            fileset(dir: "${project.basedir}/src/test/resources") {
                include(name: 'testsuite.properties')
            }

            filterset(begintoken: '%', endtoken: '%') {
                def map = [:]

                def paths = [
                    'ts.run.classpath',
                    'ts.run.classpath.ri.suffix',
                    'ts.harness.classpath',
                    'openejb.jee.classes',
                    'openejb.embedded.classpath',
                    'geronimo.specs.classpath',
                    'geronimo.porting.classes'
                ]

                paths.each{ name ->
                    map[name] = getReferenceAsString(name)
                }

                map.putAll(System.properties)
                map.putAll(project.properties)


        		// Set the profile to test. Options are:  web, full
                def options = get('options', '').tokenize(',')
                boolean javaeeFullProfile = true
                if (options.contains('web-profile')) {
                    javaeeFullProfile = false
                }
                if (javaeeFullProfile) {
                    log.info("Setting javaee.level=full")
                    map['javaee.level'] = 'full'
                }
                if (!javaeeFullProfile) {
                    log.info("Setting javaee.level=web")
                    map['javaee.level'] = 'web'
                }

                log.info("Setting bin.dir to " + javaeeCtsHome.getAbsolutePath() + "/bin")
                map['bin_dir'] = javaeeCtsHome.getAbsolutePath() + "/bin"

                // map['servlet_adaptor'] = 'org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet'
                map['servlet_adaptor'] = 'org.apache.openejb.server.rest.OpenEJBRestServlet'
                map['jaxrs_impl_name'] = 'cxf'

                map['basedir'] = project.basedir

                // Need to sanatize some properties which reference files or paths when running Windows... :-(
                if (SystemUtils.IS_OS_WINDOWS) {
                    def vars = [
                        'basedir',
                        'openejb.home',
                        'openejb.embedded.classpath',
                        'javaee.home',
                        'ri.home',
                        'javaee.home.ri',
                        'ts.run.classpath',
                        'ts.run.classpath.ri.suffix',
                        'ts.harness.classpath',
                    ]

                    vars.each {
                        def value = map[it]
                        if (value) {
                            map[it] = "$value".replace('\\', '/')
                        }
                    }
                }

                map.each {
                    filter(token: it.key, value: it.value)
                }
            }
        }

        // Make a backup of the original ts.jte file
        def originalFile = createOriginalFile("${javaeeCtsHome}/bin/ts.jte.orig", "${javaeeCtsHome}/bin/ts.jte")

        // Load the original props
        def props = loadProps(originalFile)

        // Load our custom props
        def customProps = loadProps("${project.build.directory}/testsuite.properties")

        // Merge custom w/original, custom taking precedence
        props.putAll(customProps)

        // Save the "real" ts.jte used to execute tests
        storeProps(props, "${project.build.directory}/ts.jte")

        // Dump the props as rendered above
        if (log.debugEnabled) {
            log.debug 'TS environment:'
            file.eachLine {
                log.debug "    $it"
            }
        }
    }

    def generateSigMap() {

        // Modify the sig-test_se6.map file to use the proper signature files.
        // Create backups first.
        def javaeeCtsHome = requireDirectory('cts.home')

        // Backup the original sig-test_se8.map, load in the new props, and create
        // the modified file
        def originalSe8File = createOriginalFile("${javaeeCtsHome}/bin/sig-test_se8.map.orig", "${javaeeCtsHome}/bin/sig-test_se8.map")

        // Load original properties
        def props = loadProps(originalSe8File)

        // Load custom properties
        def customProps = loadProps("${project.basedir}/src/test/resources/signature_se8.properties")

        // Merge the differences
        props.putAll(customProps)

        // Save the new properties file
        storeProps(props, "${javaeeCtsHome}/bin/sig-test_se8.map")
    }

    def createOriginalFile(newFileName, oldFileName) {

        def originalFile = new File(newFileName)

        if (!originalFile.exists()) {
            def file = new File(oldFileName)
            assert file.exists() : "Missing original file: $oldFileName"
            ant.copy(file: file, tofile: originalFile)

            // Make it harder to alter the original
            ant.chmod(perm: 'a-w', file: originalFile)
        }

        return originalFile
    }

    def loadProps(file) {
        file = new File("$file")

        def props = new SortedProperties()
        def input = file.newInputStream()
        try {
            props.load(input)
        }
        finally {
            input.close()
        }

        return props
    }

    def storeProps(props, file) {
        file = new File("$file")
        def output = file.newOutputStream()
        try {
            props.store(output, null)
        }
        finally {
            output.close()
        }
    }

    def getReferenceAsString(name) {
        return ant.getAntProject().getReference(name).toString()
    }
    
    def execute() {
        log.info("Setting up TCK environment...")
        
        // Esnure that openejb.home is now set to a directory
        def openejbHome = requireDirectory('openejb.home')

        initPaths()

        def javaeeCtsHome = get('cts.home')

        ant.mkdir(dir: "${openejbHome}/logs")
        ant.mkdir(dir: "${openejbHome}/apps")

        generateTsJte()

        generateSigMap()

        // Install the latest excludes
        ant.copy(todir: "${project.build.directory}") {
            fileset(dir: "${project.basedir}/src/test/resources") {
                include(name: 'ts.jtx')
            }
        }

        //
        // NOTE: This file *must* be placed in ${javaeeCtsHome.home}/bin, bin/tsant
        //       loads this automagically, and uses it to replace values.
        //
          ant.copy(
              file: "${project.build.directory}/ts.jte",
              tofile: "$javaeeCtsHome/bin/ts.jte",
              overwrite: true
          )

        def jaxrs = get('jaxrs')

        if(jaxrs.equals('true')){

            ant.mkdir(dir: "$javaeeCtsHome/bin/xml/impl/openejb")
            ant.copy(todir: "$javaeeCtsHome/bin/xml/impl/openejb") {
            fileset(dir: "${project.basedir}/src/test/resources/jaxrs") {
                include(name: 'cxf.xml')
            }
          }

            log.info("generating jaxrs tck dist artifacts based on vi setting")
            TsAntCommand command = new TsAntCommand(this)
            command.workingDirectory = "${javaeeCtsHome}/bin"
            command.execute('update.jaxrs.wars')

        }


        //
        // Copy openejb configuration files into server
        //
        ant.copy(todir: "${openejbHome}", filtering: true, overwrite: true) {

            def map = [:]
            map.putAll(System.properties)
            map.putAll(project.properties)

            def wcFiles

            if ("tomcat".equals(System.getProperty("webcontainer"))) {
                wcFiles = "${project.basedir}/src/test/tomcat"

            } else if ("tomee".equals(System.getProperty("webcontainer"))) {
                wcFiles = "${project.basedir}/src/test/tomee"

            } else if ("tomee-plus".equals(System.getProperty("webcontainer"))) {
                wcFiles = "${project.basedir}/src/test/tomee-plus"

            } else if ("tomee-plume".equals(System.getProperty("webcontainer"))) {
                wcFiles = "${project.basedir}/src/test/tomee-plume"

            } else {
                wcFiles = "${project.basedir}/src/test/openejb"
            }

            fileset(dir: wcFiles)
            filterset(begintoken: '%', endtoken: '%') {
                map.each {
                    filter(token: it.key, value: it.value)
                }
            }
        }

        //
        // Copy tomee-tck jar to server lib
        // this jar contains the DriverXADataSource needed for the xa tests
        //
        ant.copy(todir: "${openejbHome}/lib", overwrite: true) {
            fileset(dir: "${project.basedir}/target") {
                include(name: "tomee-tck-*.jar")
            }
        }

        //
        // Copy the clientcert.jks keystore to the conf dir
        //
        ant.copy(
            file: "${project.basedir}/src/test/keystores/clientcert.jks",
            todir: "${openejbHome}/conf"
        )
        ant.copy(
            file: "${project.basedir}/src/test/keystores/ssl-truststore",
            todir: "${openejbHome}/conf"
        )
		
        def connector = get('connector')

        if(connector.equals('true')){
            //
            // deploy the connectors
            //
            ant.copy(todir: "${openejbHome}/apps", overwrite: true) {
                fileset(dir: "${javaeeCtsHome}/dist/com/sun/ts/tests/common/connector/whitebox") {
                    include(name: "old-dd-whitebox*.rar")
                    include(name: "whitebox*.rar")
                }
                fileset(dir: "${javaeeCtsHome}/dist/com/sun/ts/tests/common/connector/whitebox/annotated") {
                    include(name: "whitebox*.rar")
                }
                fileset(dir: "${javaeeCtsHome}/dist/com/sun/ts/tests/common/connector/whitebox/ibanno") {
                    include(name: "whitebox*.rar")
                }
                fileset(dir: "${javaeeCtsHome}/dist/com/sun/ts/tests/common/connector/whitebox/mdcomplete") {
                    include(name: "whitebox*.rar")
                }
                fileset(dir: "${javaeeCtsHome}/dist/com/sun/ts/tests/common/connector/whitebox/mixedmode") {
                    include(name: "whitebox*.rar")
                }
                fileset(dir: "${javaeeCtsHome}/dist/com/sun/ts/tests/common/connector/whitebox/multianno") {
                    include(name: "whitebox*.rar")
                }
                fileset(dir: "${javaeeCtsHome}/dist/com/sun/ts/tests/common/connector/whitebox/permissiondd") {
                    include(name: "whitebox*.rar")
                }
            }
        }

        //
        // NOTE: This tsant script only needs to be run once with each new CTS image or
        //       when the DB is changed from Derby to something else. It copies tssql.stmt
        //       containing the correct DML to ${j2eetckHome}/bin where it must reside.
        //       It also updates the jstl wars as necessary for the DB selected.
        //
        // Process the dml for derby just once if it hasn't already been done
        def dmlProcessedFile = new File("${javaeeCtsHome}/dml_processed")
        if (get("reset.persistence").equals('true')) {
            dmlProcessedFile.delete()
        }
        if (!dmlProcessedFile.exists()) {
            log.info("Processing DML for Derby")

            // Ant task only works if sql file is in the correct place
            ant.mkdir(dir: "${javaeeCtsHome}/sql/derby")
            ant.copy( toDir: "${javaeeCtsHome}/sql/derby", overwrite: true ) {
                fileset(dir: "${project.basedir}/src/test/sql/derby") {
                    include(name: "derby.dml*.sql")
                }
            }

            // Configure CTS using Derby dml
            TsAntCommand command = new TsAntCommand(this)
            command.props['target.dml.file'] = 'tssql.stmt'
            command.props['dml.file'] = 'derby/derby.dml.sql'
            command.workingDirectory = "${javaeeCtsHome}/bin"
            command.execute('copy.dml.file')

            // Create flag to indicate processing is complete
            ant.touch(file: dmlProcessedFile)

        } else {
            log.info("DML already processed for Derby")
        }

        //
        // Backup previous logs (maybe)
        //
        
        def logOutputDirectory = get('logOutputDirectory', "${project.build.directory}/logs")
        def backupLogs = get('backupLogs', true)
        if (backupLogs) {
            def dir = new File("${logOutputDirectory}")
            if (dir.exists()) {
                def timestamp = System.currentTimeMillis()
                def logBackupDir = "${logOutputDirectory}-${timestamp}"
                log.info("Backing up previous logs to: ${logBackupDir}")
                
                ant.mkdir(dir: logBackupDir)
                ant.move(todir: logBackupDir) {
                    fileset(dir: logOutputDirectory) {
                        include(name: '**')
                    }
                }
            }
        }
        ant.mkdir(dir: logOutputDirectory)
		
		//
		// Stop any previous running copy of Derby, from SQL setup
		//
		//log.info("Attempting to stop Derby embedded database...")
		//Class.forName("org.apache.derby.jdbc.EmbeddedDriver")
		//DriverManager.getConnection("jdbc:derby:${openejbHome}/data/derbydb;user=cts;password=cts;shutdown=true")
		//log.info("Derby embedded database stopped.")
    }
}
