/*
 * 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:scheduler',
    ':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*",
            "org/apache/openwhisk/core/scheduler/queue/test/ElasticSearchDurationCheck*",
            "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/**",
            "org/apache/openwhisk/core/scheduler/queue/test/ElasticSearchDurationCheck*",
            "**/*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*"

    // These tests fail almost all the time in openwhisk-deploy-kube TravisCI.  Disabling to unblock PRs.
    exclude "**/*WskPackageTests*"
    exclude "**/*WskSequenceTests*"
}

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 "io.github.embeddedkafka:embedded-kafka_${gradle.scala.depVersion}:2.4.0"
    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 "io.fabric8:kubernetes-server-mock:${gradle.kube_client.version}"

    compile "com.amazonaws:aws-java-sdk-s3:1.11.295"
    compile "org.testcontainers:elasticsearch:1.12.3"

    compile project(':common:scala')
    compile project(':core:controller')
    compile project(':core:scheduler')
    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
        sourceEncoding = 'UTF-8'
        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
}
