/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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
 *
 *      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 android.support.checkapi.ApiXmlConversionTask
import android.support.checkapi.CheckApiTask
import android.support.checkapi.UpdateApiTask
import android.support.doclava.DoclavaMultilineJavadocOptionFileOption
import android.support.doclava.DoclavaTask
import android.support.jdiff.JDiffTask

import org.gradle.api.InvalidUserDataException

import groovy.io.FileType

import java.util.regex.Matcher
import java.util.regex.Pattern

// Set up platform API files for federation.
if (project.androidApiTxt != null) {
    task generateSdkApi(type: Copy) {
        description = 'Copies the API files for the current SDK.'

        // Export the API files so this looks like a DoclavaTask.
        ext.apiFile = new File(project.docsDir, 'release/sdk_current.txt')
        ext.removedApiFile = new File(project.docsDir, 'release/sdk_removed.txt')

        from project.androidApiTxt.absolutePath
        into apiFile.parent
        rename { apiFile.name }

        // Register the fake removed file as an output.
        outputs.file removedApiFile

        doLast {
            removedApiFile.createNewFile()
        }
    }
} else {
    task generateSdkApi(type: DoclavaTask, dependsOn: [configurations.doclava]) {
        description = 'Generates API files for the current SDK.'

        docletpath = configurations.doclava.resolve()
        destinationDir = project.docsDir

        classpath = project.androidJar
        source zipTree(project.androidSrcJar)

        apiFile = new File(project.docsDir, 'release/sdk_current.txt')
        removedApiFile = new File(project.docsDir, 'release/sdk_removed.txt')
        generateDocs = false

        options {
            addStringOption "stubpackages", "android.*"
        }
    }
}

// Generates online docs.
task generateDocs(type: DoclavaTask, dependsOn: [configurations.doclava, generateSdkApi]) {
    def offlineDocs = project.docs.offline
    group = JavaBasePlugin.DOCUMENTATION_GROUP
    description = 'Generates d.android.com-style documentation. To generate offline docs use ' +
            '\'-PofflineDocs=true\' parameter.'

    docletpath = configurations.doclava.resolve()
    destinationDir = new File(project.docsDir, offlineDocs ? "offline" : "online")

    // Base classpath is Android SDK, sub-projects add their own.
    classpath = project.ext.androidJar

    def hdfOption = new DoclavaMultilineJavadocOptionFileOption('hdf')
    hdfOption.add(
            ['android.whichdoc', 'online'],
            ['android.hasSamples', 'true'],
            ['dac', 'true'])

    def federateOption = new DoclavaMultilineJavadocOptionFileOption('federate')
    federateOption.add(['Android', 'https://developer.android.com'])

    def federationapiOption = new DoclavaMultilineJavadocOptionFileOption('federationapi')
    federationapiOption.add(['Android', generateSdkApi.apiFile.absolutePath])

    // Track API change history.
    def apiFilePattern = /(\d+\.\d+\.\d).txt/
    def sinceOption = new DoclavaMultilineJavadocOptionFileOption('since')
    File apiDir = new File(supportRootFolder, 'api')
    apiDir.eachFileMatch FileType.FILES, ~apiFilePattern, { File apiFile ->
        def apiLevel = (apiFile.name =~ apiFilePattern)[0][1]
        sinceOption.add([apiFile.absolutePath, apiLevel])
    }

    // Default hidden errors + hidden superclass (111) and
    // deprecation mismatch (113) to match framework docs.
    final def hidden = [105, 106, 107, 111, 112, 113, 115, 116, 121]

    doclavaErrors = (101..122) - hidden
    doclavaWarnings = []
    doclavaHidden += hidden

    options {
        addStringOption "templatedir",
                "${supportRootFolder}/../../external/doclava/res/assets/templates-sdk"
        addStringOption "stubpackages", "android.support.*"
        addStringOption "samplesdir", "${supportRootFolder}/samples"
        addOption federateOption
        addOption federationapiOption
        addOption hdfOption
        addOption sinceOption

        // Specific to reference docs.
        if (!offlineDocs) {
            addStringOption "toroot", "/"
            addBooleanOption "devsite", true
            addStringOption "dac_libraryroot", project.docs.dac.libraryroot
            addStringOption "dac_dataname", project.docs.dac.dataname
        }
    }

    exclude '**/BuildConfig.java'
}

// Generates a distribution artifact for online docs.
task distDocs(type: Zip, dependsOn: generateDocs) {
    group = JavaBasePlugin.DOCUMENTATION_GROUP
    description = 'Generates distribution artifact for d.android.com-style documentation.'

    from generateDocs.destinationDir
    destinationDir project.distDir
    baseName = "android-support-docs"
    version = project.buildNumber

    doLast {
        logger.lifecycle("'Wrote API reference to ${archivePath}")
    }
}

def MSG_HIDE_API =
        "If you are adding APIs that should be excluded from the public API surface,\n" +
        "consider using package or private visibility. If the API must have public\n" +
        "visibility, you may exclude it from public API by using the @hide javadoc\n" +
        "annotation paired with the @RestrictTo(LIBRARY_GROUP) code annotation."

// Check that the API we're building hasn't broken compatibility with the
// previously released version. These types of changes are forbidden.
def CHECK_API_CONFIG_RELEASE = [
    onFailMessage:
            "Compatibility with previously released public APIs has been broken. Please\n" +
            "verify your change with Support API Council and provide error output,\n" +
            "including the error messages and associated SHAs.\n" +
            "\n" +
            "If you are removing APIs, they must be deprecated first before being removed\n" +
            "in a subsequent release.\n" +
            "\n" + MSG_HIDE_API,
    errors: (7..18),
    warnings: [],
    hidden: (2..6) + (19..30)
]

// Check that the API we're building hasn't changed from the development
// version. These types of changes require an explicit API file update.
def CHECK_API_CONFIG_DEVELOP = [
    onFailMessage:
            "Public API definition has changed. Please run ./gradlew updateApi to confirm\n" +
            "these changes are intentional by updating the public API definition.\n" +
            "\n" + MSG_HIDE_API,
    errors: (2..30)-[22],
    warnings: [],
    hidden: [22]
]

// This is a patch or finalized release. Check that the API we're building
// hasn't changed from the current.
def CHECK_API_CONFIG_PATCH = [
    onFailMessage:
            "Public API definition may not change in finalized or patch releases.\n" +
            "\n" + MSG_HIDE_API,
    errors: (2..30)-[22],
    warnings: [],
    hidden: [22]
]

CheckApiTask createCheckApiTask(String taskName, def checkApiConfig, File oldApi, File newApi,
                                File whitelist = null) {
    return tasks.create(name: taskName, type: CheckApiTask.class) {
        doclavaClasspath = generateApi.docletpath

        onFailMessage = checkApiConfig.onFailMessage
        checkApiErrors = checkApiConfig.errors
        checkApiWarnings = checkApiConfig.warnings
        checkApiHidden = checkApiConfig.hidden

        newApiFile = newApi
        oldApiFile = oldApi
        newRemovedApiFile = new File(project.docsDir, 'release/removed.txt')
        oldRemovedApiFile = new File(supportRootFolder, 'api/removed.txt')

        whitelistErrorsFile = whitelist

        doFirst {
            logger.lifecycle "Verifying ${newApi.name} against ${oldApi.name}..."
        }
    }
}

// Generates API files.
task generateApi(type: DoclavaTask, dependsOn: configurations.doclava) {
    docletpath = configurations.doclava.resolve()
    destinationDir = project.docsDir

    // Base classpath is Android SDK, sub-projects add their own.
    classpath = project.ext.androidJar

    apiFile = new File(project.docsDir, 'release/current.txt')
    removedApiFile = new File(project.docsDir, 'release/removed.txt')
    generateDocs = false

    options {
        addStringOption "templatedir",
                "${supportRootFolder}/../../external/doclava/res/assets/templates-sdk"
        addStringOption "stubpackages", "android.support.*"
    }
    exclude '**/BuildConfig.java'
    exclude '**/R.java'
}

/**
 * Returns the most recent API, optionally restricting to APIs before
 * <code>beforeApi</code>.
 *
 * @param refApi the reference API version, ex. 25.0.0-SNAPSHOT
 * @return the most recently released API file
 */
File getApiFile(String refApi = supportVersion, boolean previous = false, boolean release = false) {
    def refMatcher = refApi =~ /^(\d+)\.(\d+)\.(\d+)(-.+)?$/
    def refMajor = refMatcher[0][1] as int
    def refMinor = refMatcher[0][2] as int
    def refPatch = refMatcher[0][3] as int
    def refExtra = refMatcher[0][4]

    File apiDir = new File(ext.supportRootFolder, 'api')

    if (!previous) {
        // If this is a patch or release version, ignore the extra.
        return new File(apiDir, "$refMajor.$refMinor.0" +
                (refPatch || release ? "" : refExtra) + ".txt")
    }

    File lastFile = null
    def lastMajor
    def lastMinor

    // Only look at released versions and snapshots thereof, ex. X.Y.0.txt or X.Y.0-SNAPSHOT.txt.
    apiDir.eachFileMatch FileType.FILES, ~/(\d+)\.(\d+)\.0(-SNAPSHOT)?\.txt/, { File file ->
        def matcher = file.name =~ /(\d+)\.(\d+)\.0(-SNAPSHOT)?\.txt/
        def major = matcher[0][1] as int
        def minor = matcher[0][2] as int

        if (lastFile == null || major > lastMajor || (major == lastMajor && minor > lastMinor)) {
            if (refMajor > major || (refMajor == major && refMinor > minor)) {
                lastFile = file
                lastMajor = major;
                lastMinor = minor;
            }
        }
    }

    return lastFile
}

String stripExtension(String fileName) {
    return fileName[0..fileName.lastIndexOf('.')-1]
}

// Make sure the API surface has not broken since the last release.
def isPatchVersion = supportVersion ==~ /\d+\.\d+.[1-9]\d*(-.+)?/
def isSnapshotVersion = supportVersion ==~ /\d+\.\d+.\d+-SNAPSHOT/
def previousApiFile = getApiFile(project.supportVersion, !isPatchVersion)
def whitelistFile = new File(
        previousApiFile.parentFile, stripExtension(previousApiFile.name) + ".ignore")
def checkApiRelease = createCheckApiTask("checkApiRelease", CHECK_API_CONFIG_RELEASE,
        previousApiFile, generateApi.apiFile, whitelistFile).dependsOn(generateApi)

// Allow a comma-delimited list of whitelisted errors.
if (project.hasProperty("ignore")) {
    checkApiRelease.whitelistErrors = ignore.split(',')
}

// Check whether the development API surface has changed.
def verifyConfig = isPatchVersion != 0 ? CHECK_API_CONFIG_DEVELOP : CHECK_API_CONFIG_PATCH;
def checkApi = createCheckApiTask("checkApi", verifyConfig, getApiFile(), generateApi.apiFile)
        .dependsOn(generateApi, checkApiRelease)

checkApi.group JavaBasePlugin.VERIFICATION_GROUP
checkApi.description 'Verify the API surface.'

rootProject.createArchive.dependsOn checkApi

task verifyUpdateApiAllowed() {
    // This could be moved to doFirst inside updateApi, but using it as a
    // dependency with no inputs forces it to run even when updateApi is a
    // no-op.
    doLast {
        if (isPatchVersion) {
            throw new GradleException("Public APIs may not be modified in patch releases.")
        } else if (isSnapshotVersion && getApiFile(supportVersion, false, true).exists()) {
            throw new GradleException("Inconsistent version. Public API file already exists.")
        } else if (!isSnapshotVersion && getApiFile().exists() && !project.hasProperty("force")) {
            throw new GradleException("Public APIs may not be modified in finalized releases.")
        }
    }
}

task updateApi(type: UpdateApiTask, dependsOn: [checkApiRelease, verifyUpdateApiAllowed]) {
    group JavaBasePlugin.VERIFICATION_GROUP
    description 'Updates the candidate API file to incorporate valid changes.'
    newApiFile = checkApiRelease.newApiFile
    oldApiFile = getApiFile()
    newRemovedApiFile = new File(project.docsDir, 'release/removed.txt')
    oldRemovedApiFile = new File(supportRootFolder, 'api/removed.txt')
    whitelistErrors = checkApiRelease.whitelistErrors
    whitelistErrorsFile = checkApiRelease.whitelistErrorsFile
}

/**
 * Converts the <code>toApi</code>.txt file (or current.txt if not explicitly
 * defined using -PtoAPi=<file>) to XML format for use by JDiff.
 */
task newApiXml(type: ApiXmlConversionTask, dependsOn: configurations.doclava) {
    classpath configurations.doclava.resolve()

    if (project.hasProperty("toApi")) {
        // Use an explicit API file.
        inputApiFile = new File(rootProject.ext.supportRootFolder, "api/${toApi}.txt")
    } else {
        // Use the current API file (e.g. current.txt).
        inputApiFile = generateApi.apiFile
        dependsOn generateApi
    }

    int lastDot = inputApiFile.name.lastIndexOf('.')
    outputApiXmlFile = new File(project.docsDir,
            "release/" + inputApiFile.name.substring(0, lastDot) + ".xml")
}

/**
 * Converts the <code>fromApi</code>.txt file (or the most recently released
 * X.Y.Z.txt if not explicitly defined using -PfromAPi=<file>) to XML format
 * for use by JDiff.
 */
task oldApiXml(type: ApiXmlConversionTask, dependsOn: configurations.doclava) {
    classpath configurations.doclava.resolve()

    if (project.hasProperty("fromApi")) {
        // Use an explicit API file.
        inputApiFile = new File(rootProject.ext.supportRootFolder, "api/${fromApi}.txt")
    } else if (project.hasProperty("toApi") && toApi.matches(~/(\d+\.){2}\d+/)) {
        // If toApi matches released API (X.Y.Z) format, use the most recently
        // released API file prior to toApi.
        inputApiFile = getApiFile(toApi, true)
    } else {
        // Use the most recently released API file.
        inputApiFile = getApiFile();
    }

    int lastDot = inputApiFile.name.lastIndexOf('.')
    outputApiXmlFile = new File(project.docsDir,
            "release/" + inputApiFile.name.substring(0, lastDot) + ".xml")
}

/**
 * Generates API diffs.
 * <p>
 * By default, diffs are generated for the delta between current.txt and the
 * next most recent X.Y.Z.txt API file. Behavior may be changed by specifying
 * one or both of -PtoApi and -PfromApi.
 * <p>
 * If both fromApi and toApi are specified, diffs will be generated for
 * fromApi -> toApi. For example, 25.0.0 -> 26.0.0 diffs could be generated by
 * using:
 * <br><code>
 *   ./gradlew generateDiffs -PfromApi=25.0.0 -PtoApi=26.0.0
 * </code>
 * <p>
 * If only toApi is specified, it MUST be specified as X.Y.Z and diffs will be
 * generated for (release before toApi) -> toApi. For example, 24.2.0 -> 25.0.0
 * diffs could be generated by using:
 * <br><code>
 *   ./gradlew generateDiffs -PtoApi=25.0.0
 * </code>
 * <p>
 * If only fromApi is specified, diffs will be generated for fromApi -> current.
 * For example, lastApiReview -> current diffs could be generated by using:
 * <br><code>
 *   ./gradlew generateDiffs -PfromApi=lastApiReview
 * </code>
 * <p>
 */
task generateDiffs(type: JDiffTask, dependsOn: [configurations.jdiff, configurations.doclava,
                                                oldApiXml, newApiXml, generateDocs]) {
    // Base classpath is Android SDK, sub-projects add their own.
    classpath = project.ext.androidJar

    // JDiff properties.
    oldApiXmlFile = oldApiXml.outputApiXmlFile
    newApiXmlFile = newApiXml.outputApiXmlFile
    newJavadocPrefix = "../../../../reference/"

    String newApi = newApiXmlFile.name
    int lastDot = newApi.lastIndexOf('.')
    newApi = newApi.substring(0, lastDot)

    // Javadoc properties.
    docletpath = configurations.jdiff.resolve()
    destinationDir = new File(project.docsDir, "online/sdk/support_api_diff/$newApi")
    title = "Support&nbsp;Library&nbsp;API&nbsp;Differences&nbsp;Report"

    exclude '**/BuildConfig.java'
    exclude '**/R.java'
}

// configuration file for setting up api diffs and api docs
void registerForDocsTask(Task task, Project subProject, releaseVariant) {
    task.dependsOn releaseVariant.javaCompile
    task.source {
        def buildConfig = fileTree(releaseVariant.getGenerateBuildConfig().sourceOutputDir)
        return releaseVariant.javaCompile.source.minus(buildConfig) +
                fileTree(releaseVariant.aidlCompile.sourceOutputDir) +
                fileTree(releaseVariant.outputs[0].processResources.sourceOutputDir)
    }

    task.classpath += releaseVariant.getCompileClasspath(null) +
            files(releaseVariant.javaCompile.destinationDir)
}

// configuration file for setting up api diffs and api docs
void registerJavaProjectForDocsTask(Task task, Project subProject, javaCompileTask) {
    task.dependsOn javaCompileTask
    task.source javaCompileTask.source
    task.classpath += files(javaCompileTask.classpath) +
            files(javaCompileTask.destinationDir)
}

subprojects { subProject ->
    subProject.afterEvaluate { p ->
        if (!p.hasProperty("noDocs") || !p.noDocs) {
            if (p.hasProperty('android') && p.android.hasProperty('libraryVariants')) {
                p.android.libraryVariants.all { v ->
                    if (v.name == 'release') {
                        registerForDocsTask(rootProject.generateDocs, p, v)
                        registerForDocsTask(rootProject.generateApi, p, v)
                        registerForDocsTask(rootProject.generateDiffs, p, v)
                    }
                }
            } else if (p.hasProperty("compileJava")) {
                registerJavaProjectForDocsTask(rootProject.generateDocs, p, p.compileJava)
            }
        }
    }
}
