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

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "gradle.plugin.org.nosphere.apache:creadur-rat-gradle:0.3.1"
    }
}

// Gogradle Config:
// https://github.com/gogradle/gogradle/blob/master/docs/getting-started.md#configuration
plugins {
    id 'com.github.blindpirate.gogradle' version '0.10'
}

apply plugin: "org.nosphere.apache.rat"

golang {
    packagePath = 'github.com/apache/openwhisk-wskdeploy' as String
    buildTags = (rootProject.findProperty('goTags')?:'').split(',')
}

// The `gogradle` plugin was designed to work with `govendor` and `godeps` tools
// We must disable its tasks that attempt to "fetch" dependencies
// into a "/vendor" directory and use them to build the project (which will fail)
installDependencies.enabled = false
resolveBuildDependencies.enabled = false
resolveTestDependencies.enabled = false

// Disable "go vet" and "gofmt" as gogradle uses deprecated syntax
goVet.enabled = false
gofmt.enabled = false

// File exclusions for the Apache Rat scanning tool
rat {
    excludes += [
        '.gradletasknamecache', 'gradle/wrapper/**', 'gradlew*', 'build/**', // Gradle
        '.gitignore', '.rat-excludes',
        'i18n_resources.go',
        '**/*.json','wski18n/resources/*'
    ]
}

/*
    The OpenWhiskPlatform class is a utility class to make the rest of what
    happens with platforms a bit more understandable.  A "Platform" is a tuple
    of an operating system and a processor.  Currently, the OpenWhisk Wskdeploy
    supports three OS's:  Linux, Mac/Darwin, and Windows.  It supports x86
    (32-bit or 64-bit) on all OS's.  On Linux, it also support System Z (s390x),
    PowerPC (ppc64le), and ARM (32-bit and 64-bit) architectures.

    Different contexts use different codings to refer to these architectures --
    the class attempts to provide and interpret all needed codings.  Internal
    storage is in "GO" format:

        OS: linux, darwin, windows
        Arch: 386, amd64, s390x, ppc64le, arm, arm64

    TODO - It may be appropriate to refactor into a general purpose Platform
           class for all builds, then to extend with specifics needed for
           the OpenWhisk Wskdeploy build.
 */
class OpenWhiskPlatform {
    String goOs
    String goArch

    /*
        The 'zipFileName' property is the root file name to use for archives.
     */
    static String zipFileName

    /*
        Create a platform for the local platform
     */
    OpenWhiskPlatform() {
        this(System.properties['os.name'], System.properties['os.arch'])
    }

    OpenWhiskPlatform(String platformSpec) {
        this(*platformSpec.split('-'))
    }

    OpenWhiskPlatform(String inOs, String inArch) {
        goOs=inOs.toLowerCase()
                .replaceAll(~/^mac.*$/,'darwin')
                .replaceAll(~/^.*n[ui]x.*$/,'linux')
        goArch=inArch.toLowerCase()
                .replaceAll('x86_64','amd64')
                .replaceAll('i386','386')
                .replaceAll('x86_32','386')
    }

    /**
     * Return the Openwhisk OS for this Platform
     */
    String getOwOs() {
        ((goOs == 'darwin') ? 'mac' : goOs)
    }

    String getGoPlatform() {
        "${goOs}-${goArch}"
    }

    /*
        Everything below here is specific to the Wskdeploy build and could be
        factored out into a subclass.
     */
    String getArchiveDirName() {
        "${this.owOs}/${goArch}"
    }

    String getArchiveFileName() {
        String suffix
        switch (goArch) {
            case "386": suffix = '-32bit'; break;
            case "amd64": suffix = ''; break;
            default: suffix = "-${goArch}"; break;
        }
        String archivetype = (goOs == 'linux') ? 'tgz' : 'zip'
        "${zipFileName}-${this.owOs}${suffix}.${archivetype}"
    }
}

/*
    Configuration of OpenWhisk Platform behavior based on environment and defaults
 */
OpenWhiskPlatform.zipFileName =
        System.env['zip_file_name'] ?:
                (rootProject.findProperty('zipFileName') ?: 'openwhisk_wskdeploy')

project.ext.packageVersion =
        rootProject.findProperty('packageVersion') ?: 'latest'

project.ext.gitCommit =
        rootProject.findProperty('gitCommit') ?: 'unset'

project.ext.buildDate =
        rootProject.findProperty('buildDate') ?: 'unset'

String buildFileName = System.env['build_file_name'] ?:
        (rootProject.findProperty('buildFileName') ?: 'wskdeploy')

/*
    'platforms' property will be null for a local compile, or a list (comma or
    space-separated) of hyphenated Goos-Goarch pairs.  Some transformation is
    done when parsing to handle misconceptions.

    TODO:  More syntax/validity checking and feedback, perhaps as part of a
    Platform object as proposed above...
*/
rootProject.ext.localPlatform = new OpenWhiskPlatform()

if (rootProject.hasProperty('buildPlatforms')) {
    rootProject.ext.platforms = buildPlatforms.tokenize(' ,').collect {
        new OpenWhiskPlatform(it)
    }
} else {
    if (!rootProject.hasProperty('nativeCompile')) {
        rootProject.ext.platforms = [
                'linux-386', 'linux-amd64',
                'linux-s390x', 'linux-ppc64le', 'linux-arm', 'linux-arm64',
                'darwin-amd64',
                'windows-386', 'windows-amd64'
        ].collect { new OpenWhiskPlatform(it) }
    } else {
        rootProject.ext.platforms = [ rootProject.localPlatform ]
    }
}

/*
    Checks -- add golint and scancode to the checks run prior to build.
       The get step is needed to be sure a golint binary is available to run.
 */
task getGoLint(type: com.github.blindpirate.gogradle.Go) {
    go 'get -u golang.org/x/lint/golint'
}

task goLint(type: com.github.blindpirate.gogradle.Go, dependsOn: getGoLint) {
    // WARNING:  The single quotes are intentional!  The gogradle plugin will
    //           parse the command with the GString engine at execution time.
    run '${GOPATH}/bin/golint ' + golang.packagePath
}

goCheck.dependsOn(goLint)

goBuild {
    targetPlatform = rootProject.platforms*.goPlatform

    // WARNING:  The single quotes are intentional!  The gogradle plugin will
    //           parse the command with the GString engine at execution time.
    go(['build',
        '-ldflags', "-X main.Version=${packageVersion} -X main.GitCommit=${gitCommit} -X main.BuildDate=${buildDate}" as String,
        '-o', './build/${GOOS}-${GOARCH}/'+buildFileName+'${GOEXE}',
        golang.packagePath ] as List<String>)
}

gofmt {
    gofmt "-s -w ."
}

task compile(type: Copy, dependsOn: goBuild) {
    destinationDir = file('./build')
    from("./build/${rootProject.localPlatform.goOs}-${rootProject.localPlatform.goArch}")
}

task build(type: DefaultTask, dependsOn: compile)

/*
    For each platform, create an individual archive in a platform appropriate
    format (tarball for Linux, zipfile for Mac & Windows).
 */
task individualArchives(
        dependsOn: rootProject.platforms.collect() { p ->
            task("release${p.goOs.capitalize()}${p.goArch.capitalize()}",
                    type: (p.goOs == 'linux') ? Tar : Zip, dependsOn: compile) {
                if (p.goOs == 'linux') { compression = Compression.GZIP }
                destinationDir = file('./release')
                baseName = "${p.zipFileName}-${packageVersion}-${p.owOs}-${p.goArch}"

                from("./build/${p.goOs}-${p.goArch}/") {
                    include "${buildFileName}*"
                }

                from("./") {
                    include "LICENSE.txt", "NOTICE.txt", "README.md", "docs/**"
                }
            }
        })

/*
    Create a 'content.json' file representing all that was
    compiled and its appropriate directory in the Tarball that will be created
    for deployment to local Nginx instances.
 */

task index() {
    def content = [:]
    for (p in platforms) {
        def pathObject = [ "path" : "${p.archiveDirName}/${p.archiveFileName}" ]
        content.get(p.owOs,[:])[p.goArch] = pathObject
        // TODO: Default architecture should be configurable as a property
        if (p.goArch == 'amd64') {
            content.get(p.owOs,[:])['default'] = pathObject
        }
    }

    doLast {
        mkdir('./build')
        file('./build/content.json').text = groovy.json.JsonOutput.toJson(["wskdeploy": content])
    }
}

task releaseBinaries(type: Tar, dependsOn: [individualArchives, index]) {
    compression = Compression.GZIP
    destinationDir = file('./release')
    baseName = "${OpenWhiskPlatform.zipFileName}-${packageVersion}-all"
    from('./build/content.json') { into('.') }
    rootProject.platforms.each() { p ->
        from('./release/') {
            include("${p.zipFileName}-${packageVersion}-${p.owOs}-${p.goArch}.*")
            into p.archiveDirName
            rename { p.archiveFileName }
        }
    }
}

task clean(type: Delete, dependsOn: goClean) {
    delete './build', './release'
}
