import java.nio.file.Files
import java.nio.file.Path as JPath
import java.nio.file.StandardCopyOption

import ch.raffael.doclets.pegdown.PegdownDoclet

import org.gradle.api.tasks.javadoc.internal.JavadocSpec
import org.gradle.jvm.internal.toolchain.JavaToolChainInternal
import org.gradle.jvm.platform.JavaPlatform
import org.gradle.jvm.platform.internal.DefaultJavaPlatform
import org.gradle.language.base.internal.compile.Compiler
// You should change this after releasing a new version of the Baku Toolkit. See the
// list of published versions at https://repo1.maven.org/maven2/io/v/baku-toolkit.
version = '0.8.1'
group = 'io.v'

def siteUrl = 'https://github.com/vanadium/java'
def gitUrl = 'https://github.com/vanadium/java.git'
def pkgDesc = 'Utilities for writing applications with distributed user interfaces'

apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'
/*
You might have to download JDK8 and set JAVA8_HOME (or set the jdk to Java 8 via Project Structure).
For detailed instructions, see https://github.com/evant/gradle-retrolambda
 */
apply plugin: 'me.tatarka.retrolambda'

archivesBaseName = 'baku-toolkit'

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        minSdkVersion 21
    }

    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
}

configurations {
    pegdown
}

dependencies {
    provided(
            /*
            https://projectlombok.org/setup/android.html
            Follow Android Studio instructions at the bottom of the page to install the Lombok
            Plugin.
             */
            'org.projectlombok:lombok:1.16.6',
            'org.slf4j:slf4j-api:1.7.12'
    )

    androidTestCompile 'org.slf4j:slf4j-android:1.7.12'

    testCompile(
            'org.mockito:mockito-core:1.10.19',
            'org.powermock:powermock-classloading-xstream:1.6.3',
            'org.powermock:powermock-module-junit4:1.6.3',
            'org.powermock:powermock-module-junit4-rule:1.6.3',
            'org.slf4j:slf4j-simple:1.7.12'
    )

    testCompile('org.powermock:powermock-api-mockito:1.6.3') {
        exclude module: 'mockito-all'
    }

    compile(
            /*
            Ideally this would be optional, but this unexpectedly becomes required if you touch
            the Baku CollectionBinding Builder, even if you don't actually try to bind to a
            RecyclerView.
             */
            'com.android.support:recyclerview-v7:23.0.1',
            'com.jakewharton.rxbinding:rxbinding:0.3.0',
            'commons-io:commons-io:2.4',
            'io.reactivex:rxandroid:1.1.0',
            'io.reactivex:rxjava:1.0.17',
            'io.reactivex:rxjava-async-util:0.21.0',
            'io.v:vanadium-android:1.7',
            'net.javacrumbs.future-converter:future-converter-guava-rxjava:0.3.0',
            'net.sourceforge.streamsupport:streamsupport:1.3.2',
            'org.robotninjas:fluent-futures:1.0'
    )

    compile fileTree(dir: 'libs', include: ['*.jar'])

    /*
    Word of caution: for local unit tests, Android log statements fail with
    UnsatisfiedLinkError (hence the slf4j-simple implementation for testCompile).

    Applications should include a suitable runtime binding, such as
    apk ('org.slf4j:slf4j-android:1.7.12')
    */

    pegdown 'ch.raffael.pegdown-doclet:pegdown-doclet:1.2'
}

install {
    repositories.mavenInstaller {
        pom {
            project {
                packaging 'aar'

                name 'Baku Toolkit'
                description pkgDesc
                url siteUrl

                licenses {
                    license {
                        name 'New BSD License'
                        url 'https://github.com/vanadium/java/blob/master/LICENSE'
                        distribution 'repo'
                    }
                }
                scm {
                    connection gitUrl
                    url siteUrl
                }
                developers {
                    developer {
                        id 'vanadium'
                        name 'The Vanadium Contributors'
                        email 'vanadium-discuss@v.io'
                    }
                }
            }
        }
    }
}

task sourcesJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier 'sources'
}

task javadoc (type: FullProcessingJavadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))

    options {
        overview 'src/main/java/overview.md'
        docletpath = configurations.pegdown.files.asType(List)
        doclet 'ch.raffael.doclets.pegdown.PegdownDoclet'
        stylesheetFile = new File('lib/src/main/java/custom-styles.css')
        bottom new File('lib/src/main/java/bottom.html').text
        group 'API Surface', 'io.v.baku.toolkit'
        group 'Component Packages', 'io.v.baku.toolkit.*:io.v.rx:io.v.rx.*'
    }

    if (JavaVersion.current().isJava8Compatible()) {
        // TODO(rosswang): Can we get rid of this?
        options.addStringOption('Xdoclint:none', '-quiet')
    }
}

/**
 * https://groups.google.com/d/topic/gradle-dev/R83dy_6PHMc/discussion
 */
@ParallelizableTask
class FullProcessingJavadoc extends Javadoc {
    private Set<File> sourceDirs

    @Override
    public void setSource(Object sourceDirs) {
        this.sourceDirs = sourceDirs
        super.setSource(sourceDirs)
    }

    @Override
    protected void generate() {
        final File destinationDir = getDestinationDir();

        if (options.getDestinationDirectory() == null) {
            options.destinationDirectory(destinationDir);
        }

        options.classpath(new ArrayList<File>(getClasspath().getFiles()));

        if (!GUtil.isTrue(options.getWindowTitle()) && GUtil.isTrue(getTitle())) {
            options.windowTitle(getTitle());
        }
        if (options instanceof StandardJavadocDocletOptions) {
            StandardJavadocDocletOptions docletOptions = (StandardJavadocDocletOptions) options;
            if (!GUtil.isTrue(docletOptions.getDocTitle()) && GUtil.isTrue(getTitle())) {
                docletOptions.setDocTitle(getTitle());
            }
        }

        if (maxMemory != null) {
            final List<String> jFlags = options.getJFlags();
            final Iterator<String> jFlagsIt = jFlags.iterator();
            boolean containsXmx = false;
            while (!containsXmx && jFlagsIt.hasNext()) {
                final String jFlag = jFlagsIt.next();
                if (jFlag.startsWith("-Xmx")) {
                    containsXmx = true;
                }
            }
            if (!containsXmx) {
                options.jFlags("-Xmx" + maxMemory);
            }
        }

        Set<JPath> roots = sourceDirs.collect { it.toPath() } as Set
        Collection<JPath> sourcePaths = source.collect{ it.toPath() }
        Set<String> packages = new HashSet<>()

        sourcePaths.each { sourcePath ->
            JPath curRoot = roots.find { sourcePath.startsWith(it) }
            JPath rel = curRoot.relativize(sourcePath)

            if (sourcePath.parent.fileName as String == "doc-files") {
                // The Pegdown doclet seems to ignore doc-files entirely, so copy them explicitly.
                JPath dest = options.destinationDirectory.toPath().resolve(rel)
                Files.createDirectories(dest.parent)
                Files.copy(sourcePath, dest, StandardCopyOption.REPLACE_EXISTING)
            } else if (rel.parent != null) {
                packages += rel.parent.toString().replaceAll("/", ".")
            }
        }
        options.setSourceNames(packages as List);
        options.addStringsOption('sourcepath').value =
                roots.collect { it.toAbsolutePath() as String }

        // Pegdown won't copy the default stylesheet if we've specified a stylesheet of our own, but
        // ours is based off the default
        Files.copy(PegdownDoclet.class.getResourceAsStream("stylesheet.8.css"),
                options.destinationDirectory.toPath().resolve("stylesheet.css"),
                StandardCopyOption.REPLACE_EXISTING)

        executeExternalJavadoc();
    }

    private void executeExternalJavadoc() {
        JavadocSpec spec = new JavadocSpec();
        spec.setExecutable(executable);
        spec.setOptions(options);
        spec.setIgnoreFailures(!failOnError);
        spec.setWorkingDir(getProject().getProjectDir());
        spec.setOptionsFile(getOptionsFile());

        Compiler<JavadocSpec> generator = ((JavaToolChainInternal) getToolChain())
                .select(getPlatform()).newCompiler(JavadocSpec.class);
        generator.execute(spec);
    }

    private static JavaPlatform getPlatform() {
        return DefaultJavaPlatform.current();
    }
}

task javadocJar(type: Jar, dependsOn: javadoc) {
    from tasks.javadoc
    classifier = 'javadoc'
}

artifacts {
    archives javadocJar
    archives sourcesJar
}

tasks.bintrayUpload.dependsOn(tasks.install)

def artifactPrefix = archivesBaseName + '-' + version

bintray {
    user = project.properties.bintrayUsername
    key = project.properties.bintrayApiKey

    configurations = ['archives']

    pkg {
        desc = pkgDesc
        websiteUrl = siteUrl
        vcsUrl = gitUrl
        repo = group
        name = archivesBaseName
        licenses = ['BSD New']
        userOrg = 'vanadium'
        publish = true

        version {
            name = project.version
            gpg {
                sign = true
            }
        }
    }
}
