/*
 * Copyright Thoughtworks, Inc.
 *
 * 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 com.thoughtworks.go.build.*

private File destFile(String url) {
  new File(gradle.gradleUserHomeDir, "download-cache/${TextUtils.md5Hex(url)}/${new File(URI.create(url).toURL().path).name}")
}

tasks.register('downloadMacJreX64Checksum', DownloadFile) {
  def goVersions = project.goVersions as GoVersions
  src goVersions.packagedJavaVersion.toSha256SumURLFor(OperatingSystem.mac, Architecture.x64)
  dest destFile(src.toString())
}

tasks.register('downloadMacJreX64', DownloadFile) {
  dependsOn downloadMacJreX64Checksum
  def goVersions = project.goVersions as GoVersions
  src goVersions.packagedJavaVersion.toDownloadURLFor(OperatingSystem.mac, Architecture.x64)
  dest destFile(src.toString())
  checksum = { downloadMacJreX64Checksum.outputs.files.singleFile.getText("utf-8").trim().split(" ").first() }
}

tasks.register('downloadMacJreArm64Checksum', DownloadFile) {
  def goVersions = project.goVersions as GoVersions
  src goVersions.packagedJavaVersion.toSha256SumURLFor(OperatingSystem.mac, Architecture.aarch64)
  dest destFile(src.toString())
}

tasks.register('downloadMacJreArm64', DownloadFile) {
  dependsOn downloadMacJreArm64Checksum
  def goVersions = project.goVersions as GoVersions
  src goVersions.packagedJavaVersion.toDownloadURLFor(OperatingSystem.mac, Architecture.aarch64)
  dest destFile(src.toString())
  checksum = { downloadMacJreArm64Checksum.outputs.files.singleFile.getText("utf-8").trim().split(" ").first() }
}

def configureMacZip(Zip zipTask, InstallerType installerType, Zip genericZipTask, Architecture arch) {
  DownloadFile downloadTask = arch == Architecture.aarch64 ? downloadMacJreArm64 : downloadMacJreX64

  zipTask.with {
    group = project.name
    description = "Build the ${installerType.baseName} osx (zip) installer"

    dependsOn downloadTask, genericZipTask

    destinationDirectory = project.base.distsDirectory.dir("osx")
    archiveBaseName = installerType.baseName
    archiveClassifier = arch == Architecture.aarch64 ? 'osx-aarch64' : 'osx'

    def goVersions = project.goVersions as GoVersions
    def genericZipTree = zipTree(genericZipTask.archiveFile)

    // dont include the wrapper.conf, and tanuki wrappers for OSes other than osx
    from(genericZipTree) {
      exclude "${installerType.baseName}-${goVersions.goVersion}/wrapper-config/wrapper.conf"
      exclude "${installerType.baseName}-${goVersions.goVersion}/wrapper/wrapper-*"
      exclude "${installerType.baseName}-${goVersions.goVersion}/wrapper/libwrapper-*"
      exclude "${installerType.baseName}-${goVersions.goVersion}/bin/*.bat"
    }

    def wrapperArch = arch == Architecture.aarch64 ? 'arm-64' : 'universal-64'

    from(genericZipTree) {
      include "${installerType.baseName}-${goVersions.goVersion}/wrapper/wrapper-macosx-${wrapperArch}"
      include "${installerType.baseName}-${goVersions.goVersion}/wrapper/libwrapper-macosx-${wrapperArch}*"
    }

    // include the wrapper.conf, but replace the java command
    from(genericZipTree) {
      include "${installerType.baseName}-${goVersions.goVersion}/wrapper-config/wrapper.conf"
      filter { String eachLine ->
        if (eachLine == 'wrapper.java.command=java') {
          eachLine = 'wrapper.java.command=jre/Contents/Home/bin/java'
        }
        eachLine
      }
    }

    // puts the content of the tar under `go-{agent,server}-XXX/jre`
    from(tarTree(downloadTask.outputs.files.singleFile)) {
      eachFile { FileCopyDetails fcd ->
        List<String> segments = fcd.relativePath.segments
        segments.set(1, "jre")
        fcd.relativePath = new RelativePath(!fcd.isDirectory(), (segments as String[]))
      }
      includeEmptyDirs = false
      into("${installerType.baseName}-${goVersions.goVersion}")
    }
  }

  zipTask.finalizedBy "${zipTask.name}Metadata"
}

tasks.register('agentMacX64Zip', Zip) { Zip thisTask ->
  configureMacZip(thisTask, InstallerType.agent, agentGenericZip, Architecture.x64)
}

tasks.register('serverMacX64Zip', Zip) { Zip thisTask ->
  configureMacZip(thisTask, InstallerType.server, serverGenericZip, Architecture.x64)
}

tasks.register('agentMacArm64Zip', Zip) { Zip thisTask ->
  configureMacZip(thisTask, InstallerType.agent, agentGenericZip, Architecture.aarch64)
}

tasks.register('serverMacArm64Zip', Zip) { Zip thisTask ->
  configureMacZip(thisTask, InstallerType.server, serverGenericZip, Architecture.aarch64)
}

['agent', 'server'].each { installerType ->
  ['X64', 'Arm64'].each { arch ->
    def packageTaskName = "${installerType}Mac${arch}Zip"
    tasks.register("${packageTaskName}Metadata", InstallerMetadataTask) {
      architecture = Architecture.canonicalize(arch)
      packageTask = project.tasks.named(packageTaskName)
      type = InstallerType."${installerType}"
    }
  }
}

assemble.dependsOn(":installers:agentMacX64Zip", ":installers:serverMacX64Zip", ":installers:agentMacArm64Zip", ":installers:serverMacArm64Zip")
