variable "EXPORT_BASE" {
  default = null
}

variable "ALPINE_VERSION" {
  default = null
}

variable "UBUNTU_VERSION" {
  default = null
}

variable "GO_VERSION" {
  default = null
}

variable "NODE_VERSION" {
  default = null
}

variable "BUILDKITD_TAGS" {
  default = null
}

variable "BUILDKIT_DEBUG" {
  default = null
}

variable "HTTP_PROXY" {
  default = null
}

variable "HTTPS_PROXY" {
  default = null
}

variable "NO_PROXY" {
  default = null
}

variable "GOBUILDFLAGS" {
  default = null
}

variable "VERIFYFLAGS" {
  default = null
}

variable "CGO_ENABLED" {
  default = null
}

variable "GOLANGCI_LINT_MULTIPLATFORM" {
  default = null
}

variable "ARCHUTIL_MULTIPLATFORM" {
  default = null
}

variable "IMAGE_TARGET" {
  default = null
}

variable "FRONTEND_CHANNEL" {
  default = "mainline"
}

variable "FRONTEND_BUILDTAGS" {
  default = null
}

# Defines the output folder
variable "DESTDIR" {
  default = ""
}

variable "TEST_COVERAGE" {
  default = null
}

variable "TEST_IMAGE_NAME" {
  default = "buildkit-tests"
}

variable "TEST_CONTEXT" {
  default = "."
  description = "Context for building the test image"
}

variable "TEST_BINARIES_CONTEXT" {
  default = TEST_CONTEXT
  description = "Context for building the buildkitd for test image"
}

variable "BUILDKIT_SYNTAX" {
  default = null
}

function "bindir" {
  params = [defaultdir]
  result = DESTDIR != "" ? DESTDIR : "./bin/${defaultdir}"
}

# Special target: https://github.com/docker/metadata-action#bake-definition
target "meta-helper" {
  tags = [IMAGE_TARGET != null && IMAGE_TARGET != "" ? "moby/buildkit:local-${IMAGE_TARGET}" : "moby/buildkit:local"]
}
target "frontend-meta-helper" {
  tags = [FRONTEND_CHANNEL != null && FRONTEND_CHANNEL != "" && FRONTEND_CHANNEL != "mainline" ? "docker/dockerfile:local-${FRONTEND_CHANNEL}" : "docker/dockerfile:local"]
}

target "_common" {
  args = {
    EXPORT_BASE = EXPORT_BASE
    ALPINE_VERSION = ALPINE_VERSION
    UBUNTU_VERSION = UBUNTU_VERSION
    GO_VERSION = GO_VERSION
    NODE_VERSION = NODE_VERSION
    BUILDKITD_TAGS = BUILDKITD_TAGS
    BUILDKIT_DEBUG = BUILDKIT_DEBUG
    HTTP_PROXY = HTTP_PROXY
    HTTPS_PROXY = HTTPS_PROXY
    NO_PROXY = NO_PROXY
    GOBUILDFLAGS = GOBUILDFLAGS
    VERIFYFLAGS = VERIFYFLAGS
    CGO_ENABLED = CGO_ENABLED
    BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
  }
}

group "default" {
  targets = ["binaries"]
}

target "binaries" {
  inherits = ["_common"]
  target = "binaries"
  output = [bindir("build")]
}

target "binaries-cross" {
  inherits = ["binaries"]
  output = [bindir("cross")]
  platforms = [
    "darwin/amd64",
    "darwin/arm64",
    "linux/amd64",
    "linux/arm/v7",
    "linux/arm64",
    "linux/s390x",
    "linux/ppc64le",
    "linux/riscv64",
    "windows/amd64",
    "windows/arm64"
  ]
}

target "binaries-for-test" {
  inherits = ["_common"]
  target = "binaries-for-test"
  output = [bindir("build")]
}

target "release" {
  inherits = ["binaries-cross"]
  target = "release"
  output = [bindir("release")]
}

target "image" {
  inherits = ["_common", "meta-helper"]
  target = IMAGE_TARGET
  cache-to = ["type=inline"]
  output = ["type=docker"]
}

target "image-cross" {
  inherits = ["image"]
  output = ["type=image,oci-artifact=true"]
  platforms = [
    "linux/amd64",
    "linux/arm/v7",
    "linux/arm64",
    "linux/s390x",
    "linux/ppc64le",
    "linux/riscv64"
  ]
}

target "frontend-image" {
  inherits = ["_common", "frontend-meta-helper"]
  dockerfile = "./frontend/dockerfile/cmd/dockerfile-frontend/Dockerfile"
  args = {
    CHANNEL = FRONTEND_CHANNEL
    BUILDTAGS = FRONTEND_BUILDTAGS
  }
  output = ["type=docker"]
}

target "frontend-image-cross" {
  inherits = ["frontend-image"]
  output = ["type=image,oci-artifact=true"]
  platforms = [
    "linux/386",
    "linux/amd64",
    "linux/arm/v7",
    "linux/arm64",
    "linux/mips",
    "linux/mipsle",
    "linux/mips64",
    "linux/mips64le",
    "linux/s390x",
    "linux/ppc64le",
    "linux/riscv64"
  ]
}

target "integration-tests-base" {
  inherits = ["_common"]
  target = "integration-tests-base"
  output = ["type=cacheonly"]
}

target "integration-tests-binaries" {
  inherits = ["_common"]
  target = "binaries"
  context = TEST_BINARIES_CONTEXT
}

target "integration-tests" {
  inherits = ["integration-tests-base"]
  target = "integration-tests"
  context = TEST_CONTEXT
  contexts = TEST_CONTEXT != TEST_BINARIES_CONTEXT ? {
    "binaries" = "target:integration-tests-binaries"
  } : null
  args = {
    GOBUILDFLAGS = TEST_COVERAGE == "1" ? "-cover" : null
    BUILDKIT_SYNTAX = BUILDKIT_SYNTAX
  }
  output = [
    "type=docker,name=${TEST_IMAGE_NAME}",
  ]
}

group "validate" {
  targets = ["lint", "validate-vendor", "validate-doctoc", "validate-dockerfile", "validate-generated-files", "validate-archutil", "validate-shfmt", "validate-docs", "validate-docs-dockerfile"]
}

target "lint" {
  name = "lint-${buildtags.name}"
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/lint.Dockerfile"
  output = ["type=cacheonly"]
  target = buildtags.target
  args = {
    TARGETNAME = buildtags.name
    BUILDTAGS = buildtags.tags
    GOLANGCI_FROM_SOURCE = "true"
  }
  platforms = ( buildtags.target == "golangci-lint" || buildtags.name == "gopls" ) && GOLANGCI_LINT_MULTIPLATFORM != null ? [
    "freebsd/amd64",
    "linux/amd64",
    "linux/arm64",
    "linux/s390x",
    "linux/ppc64le",
    "linux/riscv64",
    "windows/amd64",
    "windows/arm64"
  ] : []
  matrix = {
    buildtags = [
      { name = "default", tags = "", target = "golangci-lint" },
      { name = "labs", tags = "", target = "golangci-lint" },
      { name = "nydus", tags = "nydus", target = "golangci-lint" },
      { name = "yaml", tags = "", target = "yamllint" },
      { name = "golangci-verify", tags = "", target = "golangci-verify" },
      { name = "proto", tags = "", target = "protolint" },
      { name = "gopls", tags = "", target = "gopls-analyze" }
    ]
  }
}

target "modernize-fix" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/lint.Dockerfile"
  target = "modernize-fix"
  output = ["."]
}

target "validate-vendor" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
  target = "validate"
  output = ["type=cacheonly"]
}

target "validate-generated-files" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/generated-files.Dockerfile"
  target = "validate"
  output = ["type=cacheonly"]
}

target "validate-archutil" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/archutil.Dockerfile"
  target = "validate"
  output = ["type=cacheonly"]
  platforms = ARCHUTIL_MULTIPLATFORM != null ? [
    "linux/amd64",
    "linux/arm64"
  ] : []
}

target "validate-shfmt" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/shfmt.Dockerfile"
  target = "validate"
  output = ["type=cacheonly"]
}

target "validate-doctoc" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/doctoc.Dockerfile"
  target = "validate-toc"
  output = ["type=cacheonly"]
}

target "validate-authors" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/authors.Dockerfile"
  target = "validate"
  output = ["type=cacheonly"]
}

target "validate-docs" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/docs.Dockerfile"
  target = "validate"
  output = ["type=cacheonly"]
}

target "validate-docs-dockerfile" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/docs-dockerfile.Dockerfile"
  target = "validate"
  output = ["type=cacheonly"]
}

target "validate-dockerfile" {
  matrix = {
    dockerfile = [
      "Dockerfile",
      "./hack/dockerfiles/archutil.Dockerfile",
      "./hack/dockerfiles/authors.Dockerfile",
      "./hack/dockerfiles/docs-dockerfile.Dockerfile",
      "./hack/dockerfiles/docs.Dockerfile",
      "./hack/dockerfiles/doctoc.Dockerfile",
      "./hack/dockerfiles/generated-files.Dockerfile",
      "./hack/dockerfiles/govulncheck.Dockerfile",
      "./hack/dockerfiles/lint.Dockerfile",
      "./hack/dockerfiles/shfmt.Dockerfile",
      "./hack/dockerfiles/vendor.Dockerfile",
      "./frontend/dockerfile/cmd/dockerfile-frontend/Dockerfile",
    ]
  }
  name = "validate-dockerfile-${md5(dockerfile)}"
  inherits = ["_common"]
  dockerfile = dockerfile
  call = "check"
}

target "vendor" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
  target = "update"
  output = ["."]
}

target "generated-files" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/generated-files.Dockerfile"
  target = "update"
  output = ["."]
}

target "archutil" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/archutil.Dockerfile"
  target = "update"
  output = ["./util/archutil"]
}

target "shfmt" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/shfmt.Dockerfile"
  target = "update"
  output = ["."]
}

target "doctoc" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/doctoc.Dockerfile"
  target = "update"
  output = ["."]
}

target "authors" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/authors.Dockerfile"
  target = "update"
  output = ["."]
}

target "docs" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/docs.Dockerfile"
  target = "update"
  output = ["./docs"]
}

target "docs-dockerfile" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/docs-dockerfile.Dockerfile"
  target = "update"
  output = ["./frontend/dockerfile/docs/rules"]
}

target "gomod-updates" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
  target = "gomod-updates"
  no-cache-filter = ["gomod-updates"]
  output = ["type=cacheonly"]
}

variable "GOVULNCHECK_FORMAT" {
  default = null
}

target "govulncheck" {
  inherits = ["_common"]
  dockerfile = "./hack/dockerfiles/govulncheck.Dockerfile"
  target = "output"
  args = {
    FORMAT = GOVULNCHECK_FORMAT
  }
  no-cache-filter = ["run"]
  output = ["${DESTDIR}"]
}
