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

scoverage {
    scoverageVersion.set("${gradle.scala.scoverageVersion}")
    scoverageScalaVersion.set("${gradle.scala.scoverageScalaVersion}")
}

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/**",
            "org/apache/openwhisk/core/invoker/test/*InvokerBootUpTests*",
            "org/apache/openwhisk/core/scheduler/queue/test/ElasticSearchDurationCheck*",
            "org/apache/openwhisk/common/etcd/**",
            "**/*CacheConcurrencyTests*",
            "**/*ControllerApiTests*",
            "org/apache/openwhisk/testEntities/**",
            "invokerShoot/**"
        ]
    ],
    "REQUIRE_SYSTEM" : [
        "includes" : systemIncludes,
        "excludes": [
            "org/apache/openwhisk/core/loadBalancer/test/*FPCPoolBalancerTests*",
            "system/basic/WskMultiRuntimeTests*",
            'invokerShoot/**'
        ]
    ],
    "REQUIRE_SCHEDULER" : [
        "includes" : [
            "org/apache/openwhisk/common/etcd/**",
            "org/apache/openwhisk/core/containerpool/v2/test/**",
            "org/apache/openwhisk/core/scheduler/**",
            "org/apache/openwhisk/core/invoker/test/*InvokerBootUpTests*",
            "org/apache/openwhisk/core/service/**",
        ]
    ],
    "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 {
    implementation "org.scala-lang:scala-library:${gradle.scala.version}"
    implementation "org.apache.commons:commons-lang3:3.3.2"
    implementation "org.apache.httpcomponents:httpclient:4.5.14:tests"
    implementation "org.apache.httpcomponents:httpmime:4.3.6"
    implementation "junit:junit:4.11"
    implementation "io.rest-assured:rest-assured:4.5.1"
    implementation "org.scalatest:scalatest_${gradle.scala.depVersion}:3.0.8"
    implementation "com.typesafe.akka:akka-testkit_${gradle.scala.depVersion}:${gradle.akka.version}"
    implementation "com.google.code.gson:gson:2.10.1"
    implementation "org.scalamock:scalamock_${gradle.scala.depVersion}:4.4.0"
    implementation "com.typesafe.akka:akka-http-testkit_${gradle.scala.depVersion}:${gradle.akka_http.version}"
    implementation "com.github.java-json-tools:json-schema-validator:2.2.8"
    implementation "org.mockito:mockito-core:2.27.0"
    implementation "io.opentracing:opentracing-mock:0.31.0"
    implementation ("org.apache.curator:curator-test:${gradle.curator.version}") {
        exclude group: 'log4j'
    }
    implementation "com.atlassian.oai:swagger-request-validator-core:1.4.5"
    constraints {
        implementation("com.atlassian.oai:swagger-request-validator-core:1.4.5")
        implementation("org.slf4j:slf4j-ext:1.7.36") {
            because 'swagger-request-validator-core cannot be upgraded to 2.x where vuln is remediated'
        }
    }
    implementation "io.github.embeddedkafka:embedded-kafka_${gradle.scala.depVersion}:2.8.1"
    constraints {
        implementation("io.github.embeddedkafka:embedded-kafka_${gradle.scala.depVersion}:2.8.1")
        implementation('org.apache.avro:avro:1.11.1') {
            because 'embeddedkafka dependency cannot be upgraded currently and avro in embedded kafka 2.4.0 has vulns'
        }
    }
    implementation "com.typesafe.akka:akka-stream-kafka-testkit_${gradle.scala.depVersion}:${gradle.akka_kafka.version}"
    implementation "com.typesafe.akka:akka-stream-testkit_${gradle.scala.depVersion}:${gradle.akka.version}"
    implementation "io.fabric8:kubernetes-server-mock:${gradle.kube_client.version}"
    implementation "org.rogach:scallop_${gradle.scala.depVersion}:3.3.2"

    implementation "com.amazonaws:aws-java-sdk-s3:1.12.395"
    implementation "com.microsoft.azure:azure-cosmos:3.7.6"
    implementation 'org.testcontainers:elasticsearch:1.17.6'
    implementation 'org.testcontainers:mongodb:1.17.1'
    implementation project(':common:scala')
    implementation project(':core:controller')
    implementation project(':core:scheduler')
    implementation project(':core:invoker')
    implementation project(':core:cosmosdb:cache-invalidator')
    implementation project(':core:monitoring:user-events')
    implementation project(':tools:admin')

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

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'
        }
        dependentTasks << 'compileScoverageScala'
        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 scheduler = project(":core:scheduler")
        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, 'scheduler', "common", common)
        copyAndRenameMeasurementFile(covLogs, 'scheduler', "scheduler", scheduler)
        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')
            templateDir = file('src/test/resources/templates')
            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
}
