/*
 * 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.
 */

import org.scoverage.ScoverageReport
import static groovy.json.JsonOutput.*

plugins {
    id 'eclipse'
    id 'maven'
    id 'org.hidetake.swagger.generator' version '2.18.1'
    id 'org.scoverage'
    id 'scala'
}

compileTestScala.options.encoding = 'UTF-8'

install.dependsOn ':tools:admin:install'

project.archivesBaseName = "openwhisk-tests"

def leanExcludes = [
    '**/MaxActionDurationTests*',
    'invokerShoot/**'
]

def projectsWithCoverage = [
    ':common:scala',
    ':core:controller',
    ':core:invoker',
    ':tools:admin',
    ':core:cosmosdb:cache-invalidator'
]

def systemIncludes = [
            "org/apache/openwhisk/core/limits/**",
            "org/apache/openwhisk/core/admin/**",
            "org/apache/openwhisk/core/cli/test/**",
            "org/apache/openwhisk/core/apigw/actions/test/**",
            "org/apache/openwhisk/core/database/test/*CacheConcurrencyTests*",
            "org/apache/openwhisk/core/controller/test/*ControllerApiTests*",
            "apigw/healthtests/**",
            "ha/**",
            "services/**",
            "system/basic/**",
            "system/rest/**",
]

ext.testSets = [
    "REQUIRE_ONLY_DB" : [
        "includes" : [
            "org/apache/openwhisk/**"
        ],
        "excludes" : [
            "org/apache/openwhisk/core/admin/**",
            "org/apache/openwhisk/core/apigw/actions/test/**",
            "org/apache/openwhisk/standalone/**",
            "org/apache/openwhisk/core/cli/test/**",
            "org/apache/openwhisk/core/limits/**",
            "**/*CacheConcurrencyTests*",
            "**/*ControllerApiTests*",
            "org/apache/openwhisk/testEntities/**",
            'invokerShoot/**'
        ]
    ],
    "REQUIRE_SYSTEM" : [
        "includes" : systemIncludes,
        "excludes": [
            "system/basic/WskMultiRuntimeTests*",
            'invokerShoot/**'
        ]
    ],
    "REQUIRE_MULTI_RUNTIME" : [
        "includes" : [
            "system/basic/*MultiRuntimeTests*",
            "system/basic/*UnicodeTests*",
            "limits/**"
        ]
    ],
    "LEAN" : [
        "excludes" : leanExcludes
    ],
    "REQUIRE_SYSTEM_BASIC" : [
        "includes" : [
            "system/basic/**"
        ]
    ],
    "REQUIRE_LEAN_SYSTEM" : [
        "includes" : systemIncludes,

        // Tests suits below require Kafka so they are excluded for Lean System tests
        "excludes" : [
            "**/*KafkaConnectorTests*",
            "system/basic/WskMultiRuntimeTests*",
            "invokerShoot/**"
        ]
    ],
    "REQUIRE_STANDALONE" : [
        "includes" : [
            "org/apache/openwhisk/standalone/**"
        ]
    ]
]

testSets.each {setName, patterns ->
    def excludes = patterns["excludes"] ?: new HashSet<>()
    excludes.addAll(leanExcludes)
    patterns["excludes"] = excludes
}

//The value can be specified either via env variable
// ORG_GRADLE_PROJECT_testSetName
//Or via property -PtestSetName
if (!project.hasProperty("testSetName")) {
    ext.testSetName = "LEAN"
}

def getPattern(String name, String type) {
    def patterns = testSets[name]
    assert patterns : "No pattern found for $name"
    return patterns[type] ?: []
}

def logTestSetInfo(){
    println "Using testSet $testSetName - ${prettyPrint(toJson(testSets[testSetName]))}"
}

test {
    // Use command line option "-D testResultsDirName=<name>" to change the default test results directory ("test-results").
    // Specify a path relative to the build directory or an absolute path.
    testResultsDirName = System.getProperty('testResultsDirName', testResultsDirName)

    exclude 'invokerShoot/**'
}

task testShootInvoker(type: Test) {
    include 'invokerShoot/**'
}

task testLean(type: Test) {
    doFirst {
        logTestSetInfo()
    }
    exclude getPattern(testSetName, "excludes")
    include getPattern(testSetName, "includes")
}

task testSystemBasic(type: Test) {
    exclude getPattern("REQUIRE_SYSTEM_BASIC", "excludes")
    include getPattern("REQUIRE_SYSTEM_BASIC", "includes")
}

task testSystemKCF(type: Test) {
    exclude getPattern("REQUIRE_SYSTEM_BASIC", "excludes")
    include getPattern("REQUIRE_SYSTEM_BASIC", "includes")

    // KubernetesContainerFactory's logs API is not reliable and mixes stdout/stderr into a single stream
    exclude "**/*ActivationLogsTests*"
}

task testUnit(type: Test) {
    systemProperty("whisk.spi.ArtifactStoreProvider", "org.apache.openwhisk.core.database.memory.MemoryArtifactStoreProvider")
    exclude getPattern("REQUIRE_ONLY_DB", "excludes")
    include getPattern("REQUIRE_ONLY_DB", "includes")

    //Test below have direct dependency on CouchDB running
    def couchDbExcludes = [
        "**/*NamespaceBlacklistTests*",
        "**/*CleanUpActivationsTest*",
        "**/*CouchDbRestClientTests*",
        "**/*RemoveLogsTests*",
        "**/*ReplicatorTest*",
        "**/*CouchDBArtifactStoreTests*",
        "invokerShoot/**"
    ]

    exclude couchDbExcludes
}

dependencies {
    compile "org.scala-lang:scala-library:${gradle.scala.version}"
    compile "org.apache.commons:commons-lang3:3.3.2"
    compile "org.apache.httpcomponents:httpclient:4.5.2:tests"
    compile "org.apache.httpcomponents:httpmime:4.3.6"
    compile "junit:junit:4.11"
    compile "io.rest-assured:rest-assured:4.0.0"
    compile "org.scalatest:scalatest_${gradle.scala.depVersion}:3.0.8"
    compile "com.typesafe.akka:akka-testkit_${gradle.scala.depVersion}:${gradle.akka.version}"
    compile "com.google.code.gson:gson:2.3.1"
    compile "org.scalamock:scalamock_${gradle.scala.depVersion}:4.4.0"
    compile "com.typesafe.akka:akka-http-testkit_${gradle.scala.depVersion}:${gradle.akka_http.version}"
    compile "com.github.java-json-tools:json-schema-validator:2.2.8"
    compile "org.mockito:mockito-core:2.27.0"
    compile "io.opentracing:opentracing-mock:0.31.0"
    compile "org.apache.curator:curator-test:${gradle.curator.version}"
    compile "com.atlassian.oai:swagger-request-validator-core:1.4.5"
    compile "com.typesafe.akka:akka-stream-kafka-testkit_${gradle.scala.depVersion}:${gradle.akka_kafka.version}"
    compile "com.typesafe.akka:akka-stream-testkit_${gradle.scala.depVersion}:${gradle.akka.version}"
    compile "com.typesafe.akka:akka-stream-testkit_${gradle.scala.depVersion}:${gradle.akka.version}"
    compile "io.fabric8:kubernetes-server-mock:${gradle.kube_client.version}"

    compile "com.amazonaws:aws-java-sdk-s3:1.11.295"

    compile project(':common:scala')
    compile project(':core:controller')
    compile project(':core:invoker')
    compile project(':core:cosmosdb:cache-invalidator')
    compile project(':core:monitoring:user-events')
    compile project(':tools:admin')

    swaggerCodegen 'io.swagger:swagger-codegen-cli:2.4.9'
}

def keystorePath = new File(sourceSets.test.scala.outputDir, 'keystore')
task deleteKeystore(type: Delete) {
    delete keystorePath
}
task createKeystore(dependsOn: deleteKeystore) {
    doLast {
        def propsFile = file('../whisk.properties')
        if (propsFile.exists()) {
            Properties props = new Properties()
            props.load(new FileInputStream(propsFile))
            keystorePath.parentFile.mkdirs()
            def cmd = ['keytool', '-import', '-alias', 'Whisk', '-noprompt', '-trustcacerts', '-file', file(props['whisk.ssl.cert']), '-keystore', keystorePath, '-storepass', 'openwhisk']
            cmd.execute().waitForProcessOutput(System.out, System.err)
        }
    }
}

task buildArtifacts(type:Exec) {
  workingDir 'dat/actions'
  commandLine './build.sh'
}

tasks.withType(Test) {
    dependsOn createKeystore
    dependsOn buildArtifacts
}
createKeystore.mustRunAfter(testClasses)
buildArtifacts.mustRunAfter(testClasses)

gradle.projectsEvaluated {
    task testCoverageLean(type: Test) {
        doFirst {
            logTestSetInfo()
        }
        classpath = getScoverageClasspath(project, projectsWithCoverage)
        exclude getPattern(testSetName, "excludes")
        include getPattern(testSetName, "includes")
    }

    task testCoverage(type: Test) {
        classpath = getScoverageClasspath(project, projectsWithCoverage)
    }

    tasks.withType(ScalaCompile) {
        configure(scalaCompileOptions.forkOptions) {
            memoryMaximumSize = '1g'
        }
    }

    tasks.withType(Test) {
        systemProperties(System.getProperties())
        systemProperty("whisk.server.jar", getStandaloneJarFilePath())

        testLogging {
            events "passed", "skipped", "failed"
            showStandardStreams = true
            exceptionFormat = 'full'
        }
        maxHeapSize = "1024m" //Gradle 5.5 defaults to 512MB which is low
        outputs.upToDateWhen { false } // force tests to run every time
    }
    /**
     * Task to generate coverage xml report. Requires the
     * tests to be executed prior to its invocation
     */
    task reportCoverage(type: ScoverageReport) {
        def dependentTasks = []
        dependentTasks << copyMeasurementFiles
        projectsWithCoverage.forEach {
            dependentTasks << it + ':reportScoverage'
        }
        dependsOn(dependentTasks)
        //Need to recreate the logic from
        //https://github.com/scoverage/gradle-scoverage/blob/924bf49a8f981f119d0604b44a782f3f8eecb359/src/main/groovy/org/scoverage/ScoveragePlugin.groovy#L137
        //default tasks retrigger the tests. As ours is a multi module integration
        //test we have to adapt the classpath and hence cannot use default reportXXXScoverage tasks
        runner = new org.scoverage.ScoverageRunner(project.configurations.scoverage)
        reportDir = reportTestScoverage.reportDir
        sources = reportTestScoverage.sources
        dataDir = reportTestScoverage.dataDir
        coverageOutputCobertura = reportTestScoverage.coverageOutputCobertura
        coverageOutputXML = reportTestScoverage.coverageOutputXML
        coverageOutputHTML = reportTestScoverage.coverageOutputHTML
        coverageDebug = reportTestScoverage.coverageDebug
    }
}

task copyMeasurementFiles() {
    doLast{
        Project common = project(":common:scala")
        Project controller = project(":core:controller")
        Project invoker = project(":core:invoker")

        Properties wskProps = loadWhiskProps()
        String covLogsDir = wskProps.getProperty('whisk.coverage.logs.dir')
        assert covLogsDir : "Did not find coverage logs property 'whisk.coverage.logs.dir' in whisk props"

        File covLogs = new File(covLogsDir)

        copyAndRenameMeasurementFile(covLogs, 'controller', "common", common)
        copyAndRenameMeasurementFile(covLogs, 'controller', "controller", controller)
        copyAndRenameMeasurementFile(covLogs, 'invoker', "common", common)
        copyAndRenameMeasurementFile(covLogs, 'invoker', "invoker", invoker)
    }
}


/**
 * Scoverage measurement files are named like scoverage.measurements.xxx. Where xxx is thread id. While
 * consolidating the files between container run and normal test run we need to rename the files generated by
 * container run so that the file name becomes unique
 */
def copyAndRenameMeasurementFile(File covLogDir, String containerName, String moduleName, Project dest){
    File dir = new File(new File(covLogDir, containerName), moduleName)
    if (!dir.exists()) {
        println "Coverage logs directory ${dir.absolutePath} does not exist. Skipping measurement file collection"
        return
    }
    copy{
        from(dir)
        into("${dest.buildDir.absolutePath}/scoverage")
        rename {it+".$containerName-container"}
    }
}

def loadWhiskProps(){
    Properties p = new Properties()
    file('../whisk.properties').withInputStream {is ->
        p.load(is)
    }
    p
}

/**
 * Prepares the classpath which refer to scoverage instrumented classes from
 * dependent projects "before" the non instrumented classes
 */
def getScoverageClasspath(Project project, List<String> projectNames) {
    def combinedClasspath = projectNames.inject(project.files([])) { result, name ->
        def cp = project.project(name).sourceSets.scoverage.runtimeClasspath
        result + cp.filter {it.name.contains('scoverage')}
    }

    combinedClasspath + sourceSets.test.runtimeClasspath
}

swaggerSources {
    java {
        inputFile = file("$projectDir/../core/controller/src/main/resources/apiv1swagger.json")
        code {
            language = 'java'
            configFile = file('src/test/resources/swagger-config.json')
            dependsOn validation
        }
    }
}

task testSwaggerCodegen(type: GradleBuild) {
    dependsOn swaggerSources.java.code
    buildFile = "${buildDir}/swagger-code-java/build.gradle"
    tasks = ['build']
}

def getStandaloneJarFilePath(){
    project(":core:standalone").jar.archivePath
}
