import java.nio.file.Paths

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

apply from: "${rootProject.rootDir}/gradle/java.gradle"

project.ext.installs = new Properties()

subprojects {
  apply plugin: 'base'

  def oldGeodeVersion = project.name

  boolean isIncubating = oldGeodeVersion.contains("incubating")
  boolean useTgz = !isIncubating && ((oldGeodeVersion >= "1.7.0") || (oldGeodeVersion.length() > 5))
  boolean downloadInstall = !isIncubating && ((oldGeodeVersion >= "1.2.0") || (oldGeodeVersion.length() > 5))

  String archiveType = useTgz ? "tgz" : "zip"

  // Each project is named after its fixed version, removing dots and removing any release tags.
  // eg: 1.0.0-incubating -> test100
  def projSrcName = "test".concat(oldGeodeVersion.split(/\.|-/)
      .toList()
      .subList(0,3)
      .join(''))

  def unpackDest = project.buildDir.toPath().resolve('apache-geode-'.concat(oldGeodeVersion))

  project.configurations.create("oldInstall")

  if (downloadInstall) {
    project.dependencies.add "oldInstall", "org.apache.geode:apache-geode:${oldGeodeVersion}@${archiveType}"

    parent.ext.installs.setProperty(oldGeodeVersion, unpackDest.toString())
    project.tasks.register('downloadAndUnzipFile') {
      onlyIf { downloadInstall }
      inputs.files {
        configurations.oldInstall
      }
      outputs.dir {
        file(unpackDest)
      }

      doLast {
        def oldArchive = configurations."oldInstall".singleFile
        copy {
          from(useTgz ? tarTree(oldArchive) : zipTree(oldArchive))
          into project.buildDir
        }
      }
    }
    project.tasks.register('enumerateArchiveContents') {
      onlyIf { downloadInstall }
      inputs.files {
        downloadAndUnzipFile
      }
      def contentsFile = project.buildDir.toPath().resolve('contents.txt')
      outputs.files {
        file(contentsFile)
      }
      doLast {
        new File(contentsFile.toAbsolutePath().toString()).text = file(unpackDest).listFiles()
      }
    }
  }
}

def generatedResources = buildDir.toPath().resolve('generated-resources').resolve('test').toString()
tasks.register('createGeodeClasspathsFile') {
  def classpathsFile = Paths.get(generatedResources).resolve('geodeOldVersionClasspaths.txt').toString()
  def installsFile = Paths.get(generatedResources).resolve('geodeOldVersionInstalls.txt').toString()
  outputs.files {classpathsFile }
  outputs.files {installsFile}

  doLast {
    new FileOutputStream(classpathsFile).withStream { fos ->
      def cp = new Properties()
      project.ext.installs.each {
        File libdir = file("${it.value}/lib")
        FileCollection libJars = layout.files(libdir.listFiles())
          .filter { File f ->
            f.name.endsWith('.jar')
          }
        cp.setProperty(it.key, libJars.join(':'))
      }
      cp.store(fos, '')
    }

    // TODO potential caching issue with implicit configuration in doLast action.
    new FileOutputStream(installsFile).withStream { fos ->
      project.ext.installs.store(fos, '')
    }
  }
}

tasks.named('clean') {
  dependsOn subprojects.collect { it.tasks.named('clean') }
}

project.createGeodeClasspathsFile.mustRunAfter(clean)
project.createGeodeClasspathsFile.inputs.files(getTasksByName('downloadAndUnzipFile', true))
project.createGeodeClasspathsFile.inputs.files(getTasksByName('enumerateArchiveContents', true))
project.jarTest.dependsOn(createGeodeClasspathsFile)
tasks.named('build') {
  dependsOn(tasks.named('createGeodeClasspathsFile'))
}
sourceSets {
  test {
    output.dir(generatedResources, builtBy: createGeodeClasspathsFile)
  }
}
