import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
import com.bmuschko.gradle.docker.tasks.image.Dockerfile
/*
 * Copyright 2018 The Data Transfer Project Authors.
 *
 * Licensed 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
 *
 * https://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.
 */

/**
 * This sub-project creates a single process runtime for demonstration purposes.
 *
 * <p>
 *     To run you must acquire and set API keys for the services you want to use. See:
 *     https://github.com/google/data-transfer-project/blob/master/Documentation/Keys.md
 * <p>
 *     To run directly from a jar (e.g.
 *     java -jar distributions/demo-server/build/libs/demo-server-all.jar) you need to set
 *     the keys as environment variables.
 * <p>
 *     To run via Docker you need to copy distributions/demo-server/env.secrets.template to
 *     distributions/demo-server/env.secrets and fill in your API keys.
 */

buildscript {
    dependencies {
        // this dependency is required as a workaround to a reification error thrown when using the Docker plugin with Java 9
        classpath('javax.activation:activation:1.1.1')
    }
}

plugins {
    id 'java'
    id 'application'
    id 'com.github.johnrengelman.shadow' version '6.1.0'
    id 'com.bmuschko.docker-remote-api'
}

repositories {
    mavenCentral()
}

def transportType = project.hasProperty('transportType') ? transportType : "jettyrest"
def encryptionScheme = project.hasProperty('encryptionScheme') ? encryptionScheme : "jwe"
def offlineData = project.hasProperty('offlineData') ? offlineData : "false"
def demoDomain = project.hasProperty('appDomain') ? appDomain : "localhost"
def appPort = project.hasProperty('appPort') ? appPort : "3000"
def apiPort = project.hasProperty('apiPort') ? apiPort : "8080"


dependencies {

    compile project(':portability-bootstrap-vm')

    compile project(':portability-api')
    compile project(":extensions:transport:portability-transport-${transportType}")

    compile project(':extensions:config:portability-config-yaml')

    // TODO: depend on these based on list in flag values.

    compile project(':extensions:auth:portability-auth-apple')
    compile project(':extensions:auth:portability-auth-daybook')
    compile project(':extensions:auth:portability-auth-deezer')
    compile project(':extensions:auth:portability-auth-flickr')
    compile project(':extensions:auth:portability-auth-google')
    compile project(':extensions:auth:portability-auth-instagram')
    compile project(':extensions:auth:portability-auth-facebook')
    compile project(':extensions:auth:portability-auth-microsoft')
    compile project(':extensions:auth:portability-auth-rememberthemilk')
    compile project(':extensions:auth:portability-auth-smugmug')
    compile project(':extensions:auth:portability-auth-spotify')
    compile project(':extensions:auth:portability-auth-twitter')
    compile project(':extensions:auth:portability-auth-imgur')
    compile project(':extensions:auth:portability-auth-koofr')
    compile project(':extensions:auth:portability-auth-synology')

    compile project(':extensions:data-transfer:portability-data-transfer-apple')
    compile project(':extensions:data-transfer:portability-data-transfer-daybook')
    compile project(':extensions:data-transfer:portability-data-transfer-deezer')
    compile project(':extensions:data-transfer:portability-data-transfer-flickr')
    compile project(':extensions:data-transfer:portability-data-transfer-google')
    compile project(':extensions:data-transfer:portability-data-transfer-instagram')
    compile project(':extensions:data-transfer:portability-data-transfer-facebook')
    compile project(':extensions:data-transfer:portability-data-transfer-microsoft')
    compile project(':extensions:data-transfer:portability-data-transfer-rememberthemilk')
    compile project(':extensions:data-transfer:portability-data-transfer-smugmug')
    compile project(':extensions:data-transfer:portability-data-transfer-spotify')
    compile project(':extensions:data-transfer:portability-data-transfer-synology')
    compile project(':extensions:data-transfer:portability-data-transfer-twitter')
    compile project(':extensions:data-transfer:portability-data-transfer-imgur')
    compile project(':extensions:data-transfer:portability-data-transfer-koofr')

    if (offlineData == 'true') {
        compile project(':extensions:auth:portability-auth-offline-demo')
        compile project(':extensions:data-transfer:portability-data-transfer-offline-demo')
    }

    compile project(":extensions:security:portability-security-${encryptionScheme}")

}

addCloudExtensionDependency(project)

task createApiFile() {

    doLast {
        def apiFile = file("$buildDir/resources/main/config/api.yaml")
        apiFile.delete()
        apiFile.append("baseUrl: https://${demoDomain}:${appPort}\n")
        apiFile.append("baseApiUrl: https://${demoDomain}:${apiPort}")
    }
}


mainClassName = 'org.datatransferproject.bootstrap.vm.SingleVMMain'

// TODO: refactor this to base build.gradle so other distros (like demo-google-deployment) may use
shadowJar {
    mergeServiceFiles()
    exclude '**/pom.properties'
    exclude '**/pom.xml'
}

shadowJar.dependsOn(createApiFile)

task createDockerfile(type: Dockerfile) {
    description = 'Builds the Demo Dockerfile, which includes both the frontend served by nginx, and a combined API + transfer worker backend'
    group = 'docker'
    setDestFile(project.file("${buildDir}/demo/Dockerfile"))
    from "${javaDockerContainer}"
    // Port to open up for the debugger
    exposePort 5005

    // Update and install packages
    runCommand("apt-get update")
    runCommand("apt-get -y install nginx")
    runCommand("apt-get install -y supervisor")

    // Configure supervisor which allows multiple processes to run
    runCommand("mkdir -p /var/log/supervisor")
    copyFile("src/config/demo/supervisord.conf", "/etc/supervisor/conf.d/supervisord.conf")

    // Configure nginx and Demo client
    exposePort 3000
    // create the user nginx runs as, matches user in nginx.config
    runCommand("adduser --disabled-password nginx")
    copyFile("src/config/client/nginx.conf", "/etc/nginx")
    copyFile("build/webapp/html", "/usr/share/nginx/html")
    copyFile("build/webapp/test-keys/server.crt", "/etc/ssl/certs")
    copyFile("build/webapp/test-keys/server.key", "/etc/ssl")

    // API & Worker combined binary
    copyFile("build/libs/demo-server-${project.version}-all.jar", "/app/demo-server-all.jar")

    defaultCommand("/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf")
}

task copyWebApp {
    dependsOn ":client-rest:buildWebApp"
    doLast {
        group = 'docker'
        // The static webapp must be copied since Docker requires included files to be in a subdirectory relative to where Docker is executed
        copy {
            from '../../client-rest/dist/portability-demo'
            into 'build/webapp/html'
        }
        copy {
            from '../../client-rest/src/test-keys/server.crt'
            into 'build/webapp/test-keys'
        }
        copy {
            from '../../client-rest/src/test-keys/server.key'
            into 'build/webapp/test-keys'
        }
    }
}

task dockerize(type: DockerBuildImage) {
    description = 'Builds the Demo Docker image which includes both the frontend served by nginx, and a combined API + transfer worker backend'
    dependsOn shadowJar, createDockerfile, copyWebApp
    dockerFile = project.file("${buildDir}/demo/Dockerfile")
    inputDir = project.file(".")
    tags.add('datatransferproject/demo:latest')
}

task installToolsAndDockerize {
    description = 'Installs required build tools and builds the demo Docker image'
    group = 'docker'
    dependsOn ":client-rest:installTools", dockerize
}

