/*
 * 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.apache.tools.ant.taskdefs.condition.Os

plugins {
    id 'maven-publish'
    id 'org.scoverage'
    id 'org.springframework.boot' version '2.7.18'
    id 'scala'
    id 'com.gorylenko.gradle-git-properties' version '2.4.2'
}

ext.dockerImageName = 'standalone'
ext.dockerBuildArgs = [ "OPENWHISK_JAR=build/libs/openwhisk-standalone-${version}.jar"]
apply from: '../../gradle/docker.gradle'
distDocker.dependsOn 'bootJar'

project.archivesBaseName = "openwhisk-standalone"

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

task copySwagger(type: Copy) {
    def version = "3.6.0"
    mkdir("$buildDir/tmp/swagger")
    def destFile = file("$buildDir/tmp/swagger/swagger-ui.tar")
    def uiDir = file("$buildDir/tmp/swagger/swagger-ui")
    if (!destFile.exists()) {
        ant.get(src: "https://github.com/swagger-api/swagger-ui/archive/v${version}.tar.gz", dest: destFile)
    }
    from(tarTree(resources.gzip(destFile))){
        include("swagger-ui-${version}/dist/**")
    }
    into(uiDir)
    includeEmptyDirs = false
    project.ext.swaggerUiDir = file("$buildDir/tmp/swagger/swagger-ui/swagger-ui-${version}/dist")
}

def apiGwActions = ['createApi', "deleteApi", "getApi"]

task copyGWActions() {
    doLast {
        def routeMgmtDir = new File(project.projectDir, "../routemgmt")
        def commonDir = new File(routeMgmtDir, "common")
        def routeBuildDir = mkdir("$buildDir/tmp/routemgmt")
        apiGwActions.each { actionName ->
            def zipFileName = actionName + ".zip"
            def actionDir = new File(routeMgmtDir, actionName)
            def zipFile = new File(routeBuildDir, zipFileName)
            def npmCommand = (Os.isFamily(Os.FAMILY_WINDOWS)) ? "npm.cmd" : "npm"
            if (!zipFile.exists()) {
                ant.exec(dir:actionDir, executable:npmCommand, failonerror:true){
                    arg(line:"install")
                }
                ant.zip(destfile:zipFile){
                    fileset(dir:actionDir){
                        exclude(name:zipFileName)
                        //Somehow if in zip we add same file twice it causes issues
                        //Its possible that installRouteMgmt.sh has been invoked which would
                        //have copied the common files to each action dir.
                        //Exclude such files to zipped twice
                        commonDir.listFiles().each {f ->
                            exclude(name:f.name)
                        }
                    }
                    fileset(dir:commonDir)
                }
                logger.info("Create action zip $zipFileName")
            }
        }
    }
}

task copyGrafanaConfig() {
    doLast {
        def grafanaDir = new File(project(':core:monitoring:user-events').projectDir, "compose/grafana")
        def grafanaBuildDir = mkdir("$buildDir/tmp/grafana")
        def zipFileName = "grafana-config.zip"
        def zipFile = new File(grafanaBuildDir, zipFileName)
        if (!zipFile.exists()) {
            ant.zip(destfile:zipFile){
                fileset(dir:grafanaDir)
            }
            logger.info("Created grafana config zip $zipFileName")
        }
    }
}

processResources.dependsOn copySwagger
processResources.dependsOn copyGWActions
processResources.dependsOn copyGrafanaConfig

processResources {
    from(new File(project.projectDir, "../../ansible/files/runtimes.json")) {
        into(".")
    }
    from(new File(project.projectDir, "../../ansible/files")) {
        include "*.json"
        into("couch")
    }
    from(file("$buildDir/tmp/grafana/grafana-config.zip")){
        into(".")
    }
    from(new File(project(':core:monitoring:user-events').projectDir, "compose/prometheus/prometheus.yml")){
        into(".")
    }
    //Implement the logic present in controller Docker file
    from(project.swaggerUiDir) {
        include "index.html"
        filter {
            it.replace("http://petstore.swagger.io/v2/swagger.json", "/api/v1/api-docs")
        }
        into("swagger-ui")
    }
    from(project.swaggerUiDir) {
        exclude "index.html"
        into("swagger-ui")
    }
    apiGwActions.each { action ->
        from(file("$buildDir/tmp/routemgmt/${action}.zip")){
            into(".")
        }
    }
}

task copyBootJarToBin(type:Copy){
    from ("${buildDir}/libs")
    into file("${project.rootProject.projectDir}/bin")
    rename("${project.archivesBaseName}-${version}.jar", "${project.archivesBaseName}.jar")
}

bootJar {
    mainClass = 'org.apache.openwhisk.standalone.StandaloneOpenWhisk'
    finalizedBy copyBootJarToBin
}

// Support building standalone from source release (no .git)
gitProperties {
    failOnNoGitDirectory = false
}

// Gradle boot disables the default jar task. So need to now make
// install task depend on bootJar such that it finds the required jar file
// https://github.com/spring-projects/spring-boot/issues/13187
// install.dependsOn(bootJar)

dependencies {
    implementation "org.scala-lang:scala-library:${gradle.scala.version}"
    implementation project(':common:scala')
    implementation project(':core:controller')
    implementation project(':core:invoker')
    implementation project(':tools:admin')
    implementation "org.rogach:scallop_${gradle.scala.depVersion}:3.3.2"

    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 "org.scala-lang:scala-reflect:${gradle.scala.version}"
    implementation "ch.megard:akka-http-cors_${gradle.scala.depVersion}:0.4.2"

    testImplementation "junit:junit:4.11"
    testImplementation "org.scalatest:scalatest_${gradle.scala.depVersion}:3.0.8"
}

gradle.projectsEvaluated {
    tasks.withType(Test) {
        testLogging {
            events "passed", "skipped", "failed"
            showStandardStreams = true
            exceptionFormat = 'full'
        }
    }
}

task copyRuntimeLibs(type:Copy) {
    from configurations.runtimeClasspath
    into "$buildDir/dependency-libs"
}

tasks.named("copyBootJarToBin") {
    dependsOn tasks.named("jar")
}
