plugins {
    id 'com.avast.gradle.docker-compose' version '0.9.5'
}

ext {
    port = 8080
    if (!project.hasProperty('startPort')) {
        startPort = port
    }
    if (!project.hasProperty("sfGuiURL")) {
        sfGuiURL = "http://localhost:${port}/sfgui/" // only for build testing
    }
    if (!project.hasProperty("artifactsPath")) {
        sfGuiURL = "http://localhost:${port}/sfgui/" // only for build testing
    }
    if (incremental_build) {
        if (project.hasProperty("artifactsPath")) {
            pluginPath = artifactsPath
            sfReleasePath = artifactsPath
        } else {
            pluginPath = sharedDir
            sfReleasePath = sharedDir
        }
    } else {
        pluginPath = "${project(':BackEnd:Plugin:plugin-generic').buildDir}/release/generic"
        sfReleasePath = "${project(':FrontEnd:sailfish-frontend').buildDir}/release"
    }
}

configurations {
    runtimeClasses { transitive = false }
    runtimeSources { transitive = false }
    all {
        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
    }
}

dependencies {
    if (incremental_build) {
        testCompile group: "com.exactpro.sf", name: "sailfish-core", version: "${artifactCoreVersion}"
        testCompile group: "com.exactpro.sf", name: "sailfish-rest-api-client", version: "${artifactCoreVersion}"
    } else {
        testCompile project(':BackEnd:Core:sailfish-core')
        testCompile project(':FrontEnd:sailfish-rest-api-client')
    }
    testCompile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
    testCompile 'junit:junit:4.12'
    testCompile 'org.hamcrest:hamcrest-core:1.3'
    testCompile "org.apache.logging.log4j:log4j-slf4j-impl:${version_log4j2}"

    configurations.compileClasspath.incoming.afterResolve {
        configurations.runtime.resolvedConfiguration.resolvedArtifacts.each { ResolvedArtifact ra ->
            ModuleVersionIdentifier id = ra.moduleVersion.id
            if (id.group.startsWith('com.exactpro.sf')) {
                runtimeClasses group: id.group, name: id.name,  version: id.version
                runtimeSources group: id.group, name: id.name,  version: id.version, classifier: 'sources'
            }
        }
    }
}

task download(type: Copy) {
    into ('classes') {
        from configurations.runtimeClasses.collect { zipTree(it) }
    }
    into ('sources') {
        from configurations.runtimeSources.collect { zipTree(it) }
    }
    into "${buildDir}/download"
}

task buildJar(dependsOn: ['jar']) {
}

task unzipRelease {
    if (!incremental_build) {
        dependsOn ':FrontEnd:sailfish-frontend:zipRelease'
    }
    doLast {
        println("Looking for core artifact in ${sfReleasePath}")
        fileTree(dir: sfReleasePath)
            .include('sf_*.zip')
            .each { releaseFile ->
                println "Unpacking ${sfReleasePath}/${releaseFile.name}.."
                def zipFile = file(releaseFile)
                def outputDir = file("${buildDir}/webapps")
                copy {
                    from zipTree(zipFile)
                    include 'sfgui.war'
                    into outputDir
                }
            }
    }
}

task unzipPlugin {
    if (!incremental_build) {
        dependsOn ':BackEnd:Plugin:plugin-generic:zipRelease'
    }
    doLast {
        println("Looking for plugin artifact in ${pluginPath}")
        fileTree(dir: pluginPath)
            .include('generic*.zip')
            .each { releaseFile ->
                println "Unpacking ${pluginPath}/${releaseFile.name}.."
                def zipFile = file(releaseFile)
                def outputDir = file("${buildDir}/workspace")
                copy {
                    from zipTree(zipFile)
                    into outputDir
                }
            }
    }
}

task copyConfig(type: Copy) {
    doFirst{
        println "Copying hibernate.cfg.xml into workspace.."
    }
    from "${projectDir}/docker/cfg/"
    into "${buildDir}/workspace/cfg"
}

composeUp {
    dependsOn unzipRelease
    dependsOn unzipPlugin
    dependsOn copyConfig
    doFirst {
        def portFree = false
        def currentPort = startPort
        while (!portFree) {
            if (currentPort > startPort + 10) {
                throw new GradleException('No port probing attempts left')
            }
            try {
                println("Checking ${currentPort}...")
                def serverSocket = new ServerSocket(currentPort.toInteger());
                println("Port: ${currentPort} is free")
                serverSocket.close()
                portFree = true
                sfGuiURL = "http://localhost:${currentPort}/sfgui"
            } catch(exception) {
                println("Port: ${currentPort} is busy: ${exception.getMessage()}")
                currentPort++
            }
        }
        dockerCompose {
            projectName = currentPort
            stopContainers = true
            captureContainersOutput = false
            environment.put 'USERID', ["id", "-u"].execute().text.trim()
            environment.put 'PORT', currentPort
        }
    }
}

task integrationTest (type: Test, description: 'Runs against Docker environment') {
    doFirst {
        println "Sailfish URL: ${sfGuiURL}"
        environment 'SF_GUI_URL': "${sfGuiURL}"
        environment 'SF_EXECUTOR_URL': 'http://localhost:8080/sfgui'
        systemProperty 'matrixPath', '/var/resources/' // path to link matrices within a container
    }
}

dockerCompose {
    //captureContainersOutput = true
    stopContainers = true
    removeOrphans = true
    isRequiredBy(integrationTest)
    // allow to set the path of the docker-compose executable (useful if not present in PATH)
    // executable = '/path/to/docker-compose'
}

tasks.withType(Test) {
    maxParallelForks = 1
}

test {
    onlyIf {
        project.hasProperty('buildPipeline')
    }
    doFirst {
        println "Sailfish URL [${sfGuiURL}]"
        environment 'SF_GUI_URL': "${sfGuiURL}"
        ignoreFailures = false
    }
    jacoco {
        destinationFile = file("${buildDir}/jacoco/restAPI.exec")
    }
}
