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

// The SampleGenPlugin source is in the buildSrc directory.
import com.example.android.samples.build.SampleGenPlugin
apply plugin: SampleGenPlugin

// Add a preflight task that depends on the "refresh" task that gets
// added by the SampleGenPlugin.
task preflight {
    project.afterEvaluate({preflight.dependsOn(project.refresh)})
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.8'
}


String outPath(String buildType) {
/*
    def repoInfo = "repo info platform/developers/build".execute().text
    def buildPath = (repoInfo =~ /Mount path: (.*)/)[0][1]
*/
    return "${samplegen.pathToBuild}/out/${buildType}/${samplegen.targetSampleName()}";
}

/**
 * Collapse a path "IntelliJ-style" by putting dots rather than slashes between
 * path components that have only one child. So the two paths
 *
 * com/example/android/foo/bar.java
 * com/example/android/bar/foo.java
 *
 * Become
 * com.example.android/foo/bar.java
 * com.example.android/bar/foo.java
 *
 * @param path
 * @param roots
 * @return
 */
Map<String,String> collapsePaths(FileTree path, List<String> roots) {
    Map result = new HashMap<String,String>();

    println ("******************** Collapse *************************")

    path.visit { FileVisitDetails f ->
        if (f.isDirectory()) return;
        StringBuilder collapsedPath = new StringBuilder("${f.name}");
        File current = f.file;

        //
        // Starting at this file, walk back to the root of the path and
        // substitute dots for any directory that has only one child.
        //

        // Don't substitute a dot for the separator between the end of the
        // path and the filename, even if there's only one file in the directory.
        if (!f.isDirectory()) {
            current = current.parentFile;
            collapsedPath.insert(0, "${current.name}/")
        }

        // For everything else, use a dot if there's only one child and
        // a slash otherwise. Filter out the root paths, too--we only want
        // the relative path. But wait, Groovy/Gradle is capricious and
        // won't return the proper value from a call to roots.contains(String)!
        // I'm using roots.sum here instead of tracking down why a list of
        // strings can't return true from contains() when given a string that
        // it quite obviously does contain.
        current = current.parentFile;
        while((current != null)
                && (roots.sum {String r-> return r.equals(current.absolutePath) ? 1 : 0 } == 0)) {

            char separator = current.list().length > 1 ? '/' : '.';
            collapsedPath.insert(0, "${current.name}${separator}");
            current = current.parentFile;
        }
        result.put(f.file.path, collapsedPath.toString());
    }

    println ("******************** Results *************************")

    result.each {entry -> println("${entry}\n\n");}
    return result
}


task emitAnt(type:Copy) {
    def outputPath = outPath("ant");
    def inputPath = "${project.projectDir}/${samplegen.targetSampleModule()}"
    mkdir outputPath
    into outputPath
    includeEmptyDirs
    ["main", "common", "template"].each { input ->
        [[ "java", "src"], ["res", "res"]].each { filetype ->
            def srcPath = "${inputPath}/src/${input}/${filetype[0]}"
            into("${filetype[1]}") {
                from(srcPath)
            }
        }
    }
    from("${inputPath}/src/main") { include "AndroidManifest.xml" }
    from("${inputPath}/src/template") { include "project.properties" }
}

task emitGradle(type:Copy) {
    dependsOn(preflight)
    def outputPath = outPath("gradle")
    def inputPath = "${project.projectDir}"
    // Copy entire sample into output -- since it's already in Gradle format, we'll explicitly exclude content that
    // doesn't belong here.
    mkdir outputPath
    into outputPath
    from("${inputPath}") {
        // Paths to exclude from output
        exclude ".gradle"
        exclude "_index.jd"
        exclude "bin"
        exclude "buildSrc"
        exclude "local.properties"
        exclude "template-params.xml"
        exclude "*.iml"
        exclude "**/.idea"
        exclude "**/build"
        exclude "**/proguard-project.txt"
        exclude "${samplegen.targetSampleModule()}/**/README*.txt"

        // src directory needs to be consolidated, will be done in next section
        exclude "${samplegen.targetSampleModule()}/src/"
    }

    // Consolidate source directories
    ["main", "common", "template"].each { input ->
        ["java", "res", "assets"].each { filetype ->
            def srcPath = "${inputPath}/${samplegen.targetSampleModule()}/src/${input}/${filetype}"
            into("${samplegen.targetSampleModule()}/src/main/${filetype}") {
                from(srcPath)
            }
        }
    }

    // Copy AndroidManifest.xml
    into ("${samplegen.targetSampleModule()}/src/main") {
        from("${inputPath}/${samplegen.targetSampleModule()}/src/main/AndroidManifest.xml")
    }

    // Remove BEGIN_EXCLUDE/END_EXCLUDE blocks from source files
    eachFile { file ->
        if (file.name.endsWith(".gradle") || file.name.endsWith(".java")) {
            // TODO(trevorjohns): Outputs a blank newline for each filtered line. Replace with java.io.FilterReader impl.
            boolean outputLines = true;
            def removeExcludeBlocksFilter = { line ->
                if (line ==~ /\/\/ BEGIN_EXCLUDE/) {
                    outputLines = false;
                } else if (line ==~ /\/\/ END_EXCLUDE/) {
                    outputLines = true;
                } else if (outputLines) {
                    return line;
                }
                return ""
            }
            filter(removeExcludeBlocksFilter)
        }
    }
}

task emitBrowseable(type:Copy) {
    def outputPath =outPath("browseable");
    def inputPath = "${project.projectDir}/${samplegen.targetSampleModule()}"
    mkdir outputPath
    into outputPath

    from("${project.projectDir}/_index.jd")
    def srcDirs = ["main", "common", "template"].collect {input -> "${inputPath}/src/${input}" };
    def javaDirs = srcDirs.collect { input -> "${input}/java"}
    FileTree javaTree = null;
    javaDirs.each { dir ->
        FileTree tree = project.fileTree("${dir}")
        javaTree = (javaTree == null) ? tree : javaTree.plus(tree)}
    println javaTree;
    println srcDirs
    Map collapsedPaths = collapsePaths(javaTree, javaDirs)

    srcDirs.each { srcPath ->
        println srcPath;
        into("src") {
            def javaPath = "${srcPath}/java";
            from(javaPath)
            include(["**/*.java", "**/*.xml"])
            eachFile { FileCopyDetails fcd ->
                if (fcd.file.isFile()) {
                    def filename = fcd.name;
                    String collapsed = collapsedPaths.get(fcd.file.path);
                    fcd.path = "src/${collapsed}";
                } else {fcd.exclude()}
            }
            println "***************** done"
        }
        into("res") {
            from("${srcPath}/res")
        }
        into(".") {from("${srcPath}/AndroidManifest.xml")}
    }
}

task emitGradleZip(dependsOn: [emitBrowseable, emitGradle], type:Zip) {
    def outputPath = "${samplegen.pathToBuild}/out/browseable"
    def folderName = "${samplegen.targetSampleName()}"
    archiveName = "${samplegen.targetSampleName()}.zip"
    def inputPath = outPath("gradle")
    from inputPath
    into folderName
    include "**"
    def outDir = project.file(outputPath)
    destinationDir = outDir
}
