/*
 * Copyright 2010 the original author or 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
 *
 *      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 org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.build.docs.AssembleSamplesDocTask
import org.gradle.build.docs.Docbook2Xhtml
import org.gradle.build.docs.UserGuideTransformTask
import org.gradle.build.docs.dsl.docbook.AssembleDslDocTask
import org.gradle.build.docs.dsl.source.ExtractDslMetaDataTask
import org.gradle.build.docs.dsl.source.GenerateDefaultImportsTask
import org.gradle.build.docs.releasenotes.*
import org.gradle.build.docs.releasenotes.checks.*

evaluationDependsOn(':base:gradle')
evaluationDependsOn(':base:gradle-core')
evaluationDependsOn(':base:builder')

apply plugin: 'groovy'
apply plugin: 'base'
apply plugin: 'pegdown'
apply plugin: 'jsoup'
apply plugin: 'javascript-base'

def generatedResourcesDir = file("$buildDir/generated-resources/main")

version = rootProject.buildVersion

repositories {
    maven { url 'https://repo.gradle.org/gradle/libs' }

    javaScript.googleApis()

    ivy {
        name "Google Fonts"
        url "http://themes.googleusercontent.com/static/fonts/"
        layout 'pattern', {
            artifact '[organisation]/v[revision](/[classifier])(.[ext])'
            ivy '[organisation]/v[revision]/ivy(.[ext])'
        }
    }

    maven { url 'https://repo.gradle.org/gradle/gradle-build-internal' }
}

configurations {
    groovydocGroovy {}
    userGuideStyleSheets
    userGuideTask
    fonts
}

dependencies {
    userGuideTask 'xalan:xalan:2.7.1', 'org.codehaus.groovy:groovy-all:2.3.6'
    userGuideTask module('xhtmlrenderer:xhtmlrenderer:R8rc1') {
        dependency 'itext:itext:2.0.8@jar'
    }
    userGuideTask 'xslthl:xslthl:2.0.1@jar'

    userGuideStyleSheets 'docbook:docbook-xsl:1.75.2@zip'

    fonts \
        "lato:regular:6:v0SdcGFAl2aezM9Vq_aFTQ@ttf",
        "lato:regular-italic:6:LqowQDslGv4DmUBAfWa2Vw@ttf",
        "lato:bold:6:DvlFBScY1r-FMtZSYIYoYw@ttf",
        "lato:bold-italic:6:HkF_qI1x_noxlxhrhMQYEKCWcynf_cDxXwCLxiixG1c@ttf",
        "roboto:regular:14:zN7GBFwfMP4uA6AR0HCoLQ@ttf",
        "ubuntumono:regular:3:ViZhet7Ak-LRXZMXzuAfkZ0EAVxt0G0biEntp43Qt6E@ttf",
        "ubuntumono:regular-italic:3:KAKuHXAHZOeECOWAHsRKA-LrC4Du4e_yfTJ8Ol60xk0@ttf",
        "ubuntumono:bold:3:ceqTZGKHipo8pJj4molytp_TkvowlIOtbR7ePgFOpF4@ttf",
        "ubuntumono:bold-italic:3:n_d8tv_JOIiYyMXR4eaV9WsGzsqhEorxQDpu60nfWEc@ttf"

    groovydocGroovy 'org.codehaus.groovy:groovy-all:2.3.6'

    testCompile 'org.codehaus.groovy:groovy-all:2.3.6'
    testCompile "org.pegdown:pegdown:1.1.0"
    testCompile 'org.jsoup:jsoup:1.6.3'
    testCompile "org.gebish:geb-spock:0.9.3"
    testCompile 'org.seleniumhq.selenium:selenium-htmlunit-driver:2.42.2'
    testCompile project(":base:gradle"), project(":base:gradle-core"), project(":base:builder")
}

ext {
    srcDocsDir = file('src/fromGradle/docs')
    userguideSrcDir = new File(srcDocsDir, 'userguide')
    dslSrcDir = new File(srcDocsDir, 'dsl')
    docsDir = file("$buildDir/docs")
    userguideDir = new File(docsDir, 'userguide')
    distDocsDir = new File(buildDir, 'distDocs')
    docbookSrc = new File(project.buildDir, 'src')
}

ext.outputs = [:]
outputs.distDocs = files(distDocsDir) {
    builtBy 'distDocs'
}
outputs.docs = files(docsDir) {
    builtBy 'javadocAll', 'groovydocAll', 'userguide', 'dslHtml', 'releaseNotes'
}

tasks.withType(Docbook2Xhtml) {
    dependsOn userguideStyleSheets
    classpath = configurations.userGuideTask
    stylesheetsDir = userguideStyleSheets.destinationDir
}
tasks.withType(UserGuideTransformTask) {
    dependsOn dslDocbook
    linksFile = dslDocbook.linksFile
    websiteUrl = 'http://www.gradle.org'

    if (name in ["pdfUserguideDocbook", "userguideFragmentSrc"]) {
        // These will only be valid for releases, but that's ok
        javadocUrl = "http://www.gradle.org/docs/${->version}/javadoc"
        groovydocUrl = "http://www.gradle.org/docs/${->version}/groovydoc"
        dsldocUrl = "http://www.gradle.org/docs/${->version}/dsl"
    } else {
        javadocUrl = '../javadoc'
        groovydocUrl = '../groovydoc'
        dsldocUrl = '../dsl'
    }
}
tasks.withType(AssembleDslDocTask) {
    classDocbookDir = dslSrcDir
}

task configureCss << {
    def images = fileTree(dir: "$srcDocsDir/css/images", include: "*.*").files.collectEntries {
        [it.name, it.bytes.encodeBase64().toString()]
    }

    def fonts = configurations.fonts.resolvedConfiguration.resolvedArtifacts.collectEntries {
        def id = it.moduleVersion.id
        ["${id.group}-${id.name}".toString(), it.file.bytes.encodeBase64().toString()]
    }

    ext.tokens = images + fonts
    css.inputs.property 'tokens', tokens
    css.filter ReplaceTokens, tokens: tokens
}

task css(type: Sync, dependsOn: configureCss) {
    into "$buildDir/css"
    from "$srcDocsDir/css"
    include "*.css"
}

ext.cssFiles = fileTree(css.destinationDir) {
    builtBy css
}

task userguideStyleSheets(type: Copy) {
    File stylesheetsDir = new File(srcDocsDir, 'stylesheets')
    into new File(buildDir, 'stylesheets')
    from(stylesheetsDir) {
        include '*.xsl'
    }
    from(cssFiles)
    from({ zipTree(configurations.userGuideStyleSheets.singleFile) }) {
        // Remove the prefix
        eachFile { fcd -> fcd.path = fcd.path.replaceFirst('^docbook-xsl-[0-9\\.]+/', '') }
    }
}

task samplesDocbook(type: AssembleSamplesDocTask) {
    include '**/readme.xml'
    destFile = new File(docbookSrc, 'samplesList.xml')
}

task samplesDocs(type: Docbook2Xhtml) {
    source samplesDocbook
    stylesheetName = 'standaloneHtml.xsl'
}

task dslMetaData(type: ExtractDslMetaDataTask) {
    source { groovydocAll.source }
    destFile = new File(docbookSrc, 'dsl-meta-data.bin')
}

task dslDocbook(type: AssembleDslDocTask, dependsOn: [dslMetaData]) {
    inputs.files fileTree(dir: dslSrcDir, includes: ['*.xml'])
    sourceFile = new File(dslSrcDir, 'dsl.xml')
    classMetaDataFile = dslMetaData.destFile

    pluginsMetaDataFile = new File(dslSrcDir, 'plugins.xml')
    destFile = new File(docbookSrc, 'dsl.xml')
    linksFile = new File(docbookSrc, 'api-links.bin')
}

task dslStandaloneDocbook(type: UserGuideTransformTask, dependsOn: [dslDocbook]) {
    sourceFile = dslDocbook.destFile
    snippetsDir = buildDir
    destFile = new File(docbookSrc, 'dsl-standalone.xml')
    dsldocUrl = '.'
}

task defaultImports(type: GenerateDefaultImportsTask, dependsOn: dslMetaData) {
    metaDataFile = dslMetaData.destFile
    destFile = new File(generatedResourcesDir, "default-imports.txt")
    // These are part of the API, but not the DSL
    excludePackage 'org.gradle.tooling.**'
    excludePackage 'org.gradle.testfixtures.**'

    // Tweak the imports due to some inconsistencies introduced before we automated the default-imports generation
    excludePackage 'org.gradle.plugins.ide.eclipse.model'
    excludePackage 'org.gradle.plugins.ide.idea.model'
    excludePackage 'org.gradle.api.tasks.testing.logging'
    extraPackage 'org.gradle.util'

    // TODO - rename some incubating types to remove collisions and then remove these exclusions
    excludePackage 'org.gradle.plugins.binaries.model'
    excludePackage 'org.gradle.ide.cdt.model'
}

task dslHtml(type: Docbook2Xhtml) {
    source dslStandaloneDocbook
    destDir = new File(docsDir, 'dsl')
    stylesheetName = 'dslHtml.xsl'
    resources = cssFiles + fileTree(dslSrcDir) {
        include '*.js'
    }
}

task dslHtmlZip(type: Zip) {
  dependsOn dslHtml
  from dslHtml.destDir
  destinationDir docsDir
  baseName 'gradle-dsl'
}

def javaApiUrl = "http://docs.oracle.com/javase/1.6.0/docs/api/"
def groovyApiUrl = "http://groovy.codehaus.org/gapi/"
def publicGroovyProjects = [
        project(":base:gradle"),
        project(":base:gradle-core"),
        project(":base:builder")
]

task javadocAll(type: Javadoc) {
//    ext.stylesheetFile = file("src/docs/css/javadoc.css")
//    inputs.file stylesheetFile

    group = 'documentation'
    options.encoding = 'utf-8'
    options.docEncoding = 'utf-8'
    options.charSet = 'utf-8'
    if (JavaVersion.current().isJava8Compatible()) {
        options.addStringOption 'Xdoclint:none', '-quiet'
    }
//    options.addStringOption "stylesheetfile", stylesheetFile.absolutePath
    source publicGroovyProjects.collect {project -> project.sourceSets.main.allJava }
    destinationDir = new File(docsDir, 'javadoc')
    classpath = files(publicGroovyProjects.collect {project -> [project.sourceSets.main.compileClasspath, project.sourceSets.main.output] })
//    include 'org/gradle/*'
//    include 'org/gradle/api/**'
    include 'com/android/build/gradle/**'
    include 'com/android/build/gradle/internal/dsl/**'
    include 'com/android/builder/**'
//    exclude '**/internal/**'
    options.links(javaApiUrl, groovyApiUrl, "http://maven.apache.org/ref/2.2.1/maven-core/apidocs",
        "http://maven.apache.org/ref/2.2.1/maven-model/apidocs")
    doFirst {
        title = "Android plugin API $version"
    }
}

task configureGroovydocAll {
    doFirst {
        project.configure(groovydocAll) {
            [javaApiUrl, groovyApiUrl].each {
                link(it, *(new URL("$it/package-list").text.tokenize("\n")))
            }
            docTitle = "Gradle API $version"
            windowTitle = "Gradle API $version"
            footer = "Gradle API $version"
        }
    }
}

task groovydocAll(type: Groovydoc, dependsOn: configureGroovydocAll) {
    group = 'documentation'
    source publicGroovyProjects.collect {project ->
        def main = project.sourceSets.main
        try {
            main.groovy + main.java
        } catch (MissingPropertyException e) {
            main.java
        }
    }
    destinationDir = new File(docsDir, 'groovydoc')

    // Groovydoc runs static initializers, and at least ProjectBuilder's initializers depend on runtime classes
    // http://jira.codehaus.org/browse/GROOVY-7096
    classpath = files(publicGroovyProjects.collect {project -> [project.sourceSets.main.runtimeClasspath, project.sourceSets.main.output] })

    includes = javadocAll.includes
    excludes = javadocAll.excludes
    doFirst {
        windowTitle = "Gradle API $version"
        docTitle = windowTitle
    }
    groovyClasspath = configurations.groovydocGroovy
    doLast {
        def index = new File(destinationDir, "index.html")
        index.text = index.text.replace("{todo.title}", windowTitle) // workaround groovydoc bug
    }
}

task docsAll {
    dependsOn groovydocAll, dslHtml
    description = 'Generates all documentation'
    group = 'documentation'
}

// Make sure all the references are valid and up-to-date. Hopefully this will mark the build
// red in Jenkins if they get out of sync.
check.dependsOn dslHtml
