/*
 * 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 groovy.json.JsonOutput

plugins {
  id 'base'
}

subprojects {
  apply plugin: 'base'
}

static def useRegistryMirror() {
  System.env.DOCKERHUB_MIRROR_USERNAME && System.env.DOCKERHUB_MIRROR_PASSWORD
}

def configureDockerRegistryMirror = tasks.register('configureDockerRegistryMirror') {
  def skipDockerBuild = project.hasProperty('skipDockerBuild')
  doFirst {
    if (!skipDockerBuild && useRegistryMirror()) {
      logger.lifecycle("Configuring dockerhub mirror credentials, assuming docker.gocd.io is configured...")
      def dockerConfig = file("${System.properties['user.home']}/.docker/config.json")
      dockerConfig.parentFile.mkdirs()

      // See https://github.com/moby/moby/issues/30880#issuecomment-798807332 for why normal docker login to docker.gocd.io as registry mirror doesn't work
      // Docker uses the wrong credentials when trying to use a registry mirror, so we set the docker.gocd.io creds for Docker Hub
      dockerConfig.text = JsonOutput.toJson([
        auths: [
          "https://index.docker.io/v1/": [
            auth: "${System.env.DOCKERHUB_MIRROR_USERNAME}:${System.env.DOCKERHUB_MIRROR_PASSWORD}".bytes.encodeBase64().toString()
          ]
        ]
      ])
    }
  }
}

tasks.register('initializeBuildx') {
  dependsOn configureDockerRegistryMirror

  def injected = project.objects.newInstance(Injected)
  def skipDockerBuild = project.hasProperty('skipDockerBuild')

  doFirst {
    if (!skipDockerBuild) {
      // Need to do once before everything (not in parallel) see https://github.com/docker/buildx/issues/344
      def builderName = 'gocd-builder'
      logger.lifecycle("Initializing docker buildx builder [$builderName]...")

      def buildkitConfig = layout.projectDirectory.file(useRegistryMirror() ? 'buildkitd-mirror.toml' : 'buildkitd-empty.toml').asFile

      injected.execOps.exec { commandLine = ['docker', 'buildx', 'version'] }
      injected.execOps.exec {
        commandLine = ['docker', 'buildx', 'rm', '--force', '--keep-state', builderName]
        ignoreExitValue = true
      }
      injected.execOps.exec { commandLine = ['docker', 'buildx', 'create', '--use', '--name', builderName, '--config', buildkitConfig.path, '--driver-opt', 'image=moby/buildkit:v0.19.0-rootless'] }
      injected.execOps.exec { commandLine = ['docker', 'buildx', 'inspect', '--bootstrap', builderName] }
    }
  }
}

assemble.dependsOn(subprojects.tasks*.named('assemble'))
