data "http" "script" {
  url = var.script_url

  retry {
    attempts     = 3
    min_delay_ms = 1000
    max_delay_ms = 5000
  }
}

data "http" "destroy_script" {
  url = var.destroy_script_url != "" ? var.destroy_script_url : var.script_url

  retry {
    attempts     = 3
    min_delay_ms = 1000
    max_delay_ms = 5000
  }
}

locals {
  job_name = format(
    "%s-%s",
    element(split(".", replace(basename(var.script_url), "_", "-")), 0),
    substr(md5(join("", concat([
      data.http.script.response_body,
    ], var.script_parameters))), 0, 8),
  )

  job_manifest = templatefile("${path.module}/job.yml.tpl", {
    job_name = local.job_name
    command  = jsonencode(concat(["uv", "run", var.script_url], var.script_parameters))
  })

  has_destroy_script = var.destroy_script_url != ""

  destroy_job_name = local.has_destroy_script ? format(
    "%s-%s",
    element(split(".", replace(basename(var.destroy_script_url), "_", "-")), 0),
    substr(md5(join("", concat([
      data.http.destroy_script.response_body,
    ], var.destroy_script_parameters))), 0, 8),
  ) : ""

  destroy_command_json = local.has_destroy_script ? jsonencode(
    concat(["uv", "run", var.destroy_script_url], var.destroy_script_parameters)
  ) : ""

  destroy_job_manifest = local.has_destroy_script ? templatefile("${path.module}/job.yml.tpl", {
    job_name = local.destroy_job_name
    command  = local.destroy_command_json
  }) : ""
}

resource "null_resource" "job" {
  lifecycle {
    ignore_changes = all
  }

  triggers = {
    job_name             = nonsensitive(local.job_name)
    kubeconfig_path      = var.kubeconfig_path
    has_destroy_script   = tostring(local.has_destroy_script)
    destroy_job_name     = nonsensitive(local.destroy_job_name)
    destroy_job_manifest = nonsensitive(local.destroy_job_manifest)
  }

  provisioner "local-exec" {
    when        = create
    interpreter = ["bash", "-c"]
    environment = {
      KUBECONFIG = var.kubeconfig_path
    }
    command = <<-EOT
      set -eou pipefail

      kubectl replace --force --validate=false -f - <<'EOF'
      ${local.job_manifest}
      EOF

      kubectl wait --for=condition=complete job/${local.job_name} --timeout=5m -n default
      kubectl logs job/${local.job_name} -n default
    EOT
  }

  provisioner "local-exec" {
    when        = destroy
    interpreter = ["bash", "-c"]
    environment = {
      KUBECONFIG = self.triggers.kubeconfig_path
    }
    command = <<-EOT
      set -eou pipefail

      kubectl delete job/${self.triggers.job_name} -n default --ignore-not-found

      if [ "${self.triggers.has_destroy_script}" = "true" ]; then
        echo '${base64encode(self.triggers.destroy_job_manifest)}' | base64 -d | kubectl replace --force --validate=false -f -

        kubectl wait --for=condition=complete job/${self.triggers.destroy_job_name} --timeout=5m -n default
        kubectl logs job/${self.triggers.destroy_job_name} -n default
      fi
    EOT
  }
}