// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file was auto-generated via go generate.
// DO NOT UPDATE MANUALLY

package main

const gradleInitScript = `// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

import groovy.json.*;

allprojects {

    // Add the extract task only to the project in the current directory.
    if (project.projectDir == gradle.startParameter.currentDir) {
        task madbExtractVariantProperties << {
            extract(project)
        }
    }
}

// Main driver of the property extraction script.
void extract(project) {
    project = getApplicationModule(project)
    if (project == null) {
        def errMsg = 'The current project is not an Android application module, '
            + 'nor does it contain any application sub-modules. '
            + 'Please run the madb command from an Android application project directory.'
        throw new GradleException(errMsg)
    }

    // Get the target variant.
    def targetVariant = getTargetVariant(project)

    // Collect the variant properties in a map, so that it can be printed out as a JSON.
    def result = [
        ProjectPath:    project.path,
        VariantName:    targetVariant.name,
        CleanTask:      project.path + ":clean",
        AssembleTask:   targetVariant.assemble.path,
        AppID:          getApplicationId(targetVariant),
        Activity:       getMainActivity(project),
        AbiFilters:     getAbiFilters(targetVariant),
        VariantOutputs: getVariantOutputs(targetVariant)
    ]

    // Format the resulting map into JSON and print it.
    def resultJson = JsonOutput.prettyPrint(JsonOutput.toJson(result))
    printResult(project, resultJson)
}

// Prints the given result to the desired output stream.
// If the output file is specified, write the result to the file.
// Otherwise, print it out to the console.
void printResult(project, result) {
    // An optional output file name can be specified by a Gradle command-line flag:
    // -PmadbOutputFile=<file_name>
    def output = project.properties.containsKey('madbOutputFile')
        ? new File(project.properties['madbOutputFile'])
        : null

    if (output != null) {
        // Empty the file, and then print the result.
        output.text = ''
        output.append(result)
    } else {
        println result
    }
}

// Returns an Android application module from the given project.
// The given project is returned immediately, if itself is an application module.
// Otherwise, the first available application sub-module is returned, if any.
// Returns null if no Android application modules were found from the given project.
Object getApplicationModule(project) {
    if (isApplicationModule(project)) {
        return project
    }

    def subApplicationModules = project.subprojects.findAll { isApplicationModule(it) }
    if (subApplicationModules.isEmpty()) {
        return null
    }

    def result = subApplicationModules.first()
    if (subApplicationModules.size() > 1) {
        print 'Multiple application sub-modules were detected. '
        println 'The first application module "' + result.name + '" is chosen automatically.'
        println '(NOTE: Application module can be explicitly specified using -module=<name> flag.)'
    }

    return result
}

// Returns true iff the given project is an Android application.
boolean isApplicationModule(project) {
    return project.plugins.hasPlugin('com.android.application')
}

// Returns the target application variant for the project.
// If the 'madbVariant' property was explicitly set from the command line, the
// matching variant is returned.
// If there is no variant with the provided name, it throws an exception.
//
// If the 'madbVariant' property is not provided, the first available variant is
// returned. Usually the first available variant would be 'debug'.
Object getTargetVariant(project) {
    def allVariants = project.android.applicationVariants

    if (project.properties.containsKey('madbVariant')) {
        def variantName = project.properties['madbVariant']
        def targetVariant = allVariants.find { variantName.equalsIgnoreCase(it.name) }
        if (targetVariant == null) {
            throw new GradleException('Variant "' + variantName + '" is not found.')
        }

        return targetVariant
    } else {
        def targetVariant = allVariants.iterator().next()
        print 'Build variant not specified. '
        println 'The first variant "' + targetVariant.name + '" is chosen automatically.'
        println '(NOTE: Variant can be explicitly specified using -variant=<name> flag.)'

        return targetVariant
    }
}

// Returns the application ID for the given variant.
String getApplicationId(variant) {
    def suffix = variant.buildType.applicationIdSuffix
    if (suffix == null) {
        suffix = ""
    }

    return variant.mergedFlavor.applicationId + suffix
}

String getMainActivity(project) {
    def manifestFile = getAndroidManifestLocation(project)

    // Parse the xml file and find the main activity.
    def manifest = new XmlSlurper().parse(manifestFile)
    def mainActivity = manifest.application.activity.find { isMainActivity(it) }
    def name = mainActivity.'@android:name'.text()

    // If the activity name is using the shorthand syntax starting with a dot,
    // make it a fully-qualified name by prepending it with the package name.
    if (name.startsWith('.')) {
        return manifest.'@package'.text() + name
    } else {
        return name
    }
}

// Returns the location of the "AndroidManifest.xml" file.
// TODO(youngseokyoon): investigate whether we can obtain the merged manifest.
File getAndroidManifestLocation(project) {
    try {
        return project.android.sourceSets.main.manifest.srcFile
    } catch (all) {
        return null
    }
}

// Determines whether the given activity is the main activity or not.
boolean isMainActivity(activity) {
    try {
        def intentFilter = activity.'intent-filter'
        return  intentFilter.action.'@android:name'.text() == 'android.intent.action.MAIN' &&
                intentFilter.category.'@android:name'.text() == 'android.intent.category.LAUNCHER'
    } catch (all) {
        return false
    }
}

// Returns the list of supported ABIs for the given variant.
// Returns null if there are no ABI filters specified.
Object getAbiFilters(variant) {
    return variant.variantData.variantConfiguration.supportedAbis
}

// Gets the outputs and their properties of the given variant.
// The returned object is a list of variant outputs, each of which is a map containing the
// properties of a variant output, such as the absolute path of the .apk file, and its filters.
Object getVariantOutputs(variant) {
    def variantOutputs = []
    for (def variantOutput : variant.outputs) {
        def filters = []
        for (def filter : variantOutput.mainOutputFile.filters) {
            filters.add([FilterType: filter.filterType, Identifier: filter.identifier])
        }

        def result = [
            Name: variantOutput.name,
            OutputFilePath: variantOutput.mainOutputFile.outputFile.absolutePath,
            VersionCode: variantOutput.versionCode,
            Filters: filters
        ]

        variantOutputs.add(result)
    }

    return variantOutputs
}
`
