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()
      }
    }
    project.assemble.dependsOn(project.downloadAndUnzipFile)
    project.assemble.dependsOn(project.enumerateArchiveContents)

  }
}

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, '')
    }
  }
}

project.createGeodeClasspathsFile.mustRunAfter(clean)
project.createGeodeClasspathsFile.inputs.files(getTasksByName('downloadAndUnzipFile', true))
project.createGeodeClasspathsFile.inputs.files(getTasksByName('enumerateArchiveContents', true))
project.jarTest.dependsOn(createGeodeClasspathsFile)

sourceSets {
  test {
    output.dir(generatedResources, builtBy: createGeodeClasspathsFile)
  }
}
