resource "kubernetes_namespace" "argocd" {
  metadata {
    name = "argocd"
  }
}

# Install cert-manager
resource "helm_release" "cert_manager" {
  name             = "cert-manager"
  repository       = "https://charts.jetstack.io"
  chart            = "cert-manager"
  version          = "v1.18.2"
  namespace        = "cert-manager"
  create_namespace = true

  set {
    name  = "installCRDs"
    value = "true"
  }

  set {
    name  = "prometheus.enabled"
    value = "false"
  }

  set {
    name  = "webhook.timeoutSeconds"
    value = "4"
  }
}

# Install nginx-ingress
resource "helm_release" "ingress_nginx" {
  name             = "ingress-nginx"
  repository       = "https://kubernetes.github.io/ingress-nginx"
  chart            = "ingress-nginx"
  version          = "4.14.2"
  namespace        = "ingress-nginx"
  create_namespace = true

  set {
    name  = "controller.service.type"
    value = "NodePort"
  }

  set {
    name  = "controller.service.nodePorts.http"
    value = "80"
  }

  set {
    name  = "controller.service.nodePorts.https"
    value = "443"
  }

  set {
    name  = "controller.ingressClassResource.default"
    value = "true"
  }

  set {
    name  = "controller.watchIngressWithoutClass"
    value = "true"
  }

  set {
    name  = "controller.hostPort.enabled"
    value = "true"
  }

  set {
    name  = "controller.service.externalTrafficPolicy"
    value = "Local"
  }
  set {
    name  = "controller.metrics.enabled"
    value = "true"
  }
  set {
    name  = "controller.metrics.serviceMonitor.enabled"
    value = "true"
  }
  set {
    name  = "controller.metrics.serviceMonitor.namespace"
    value = "prometheus"
  }
  set {
    name  = "controller.metrics.serviceMonitor.additionalLabels.release"
    value = "prometheus"
  }
  set {
    name  = "controller.metrics.serviceMonitor.additionalLabels.app"
    value = "ingress-nginx"
  }

}

# Check for cert-manager CRDs before proceeding
resource "null_resource" "wait_for_cert_manager_crds" {
  depends_on = [helm_release.cert_manager]

  provisioner "local-exec" {
    command = <<-EOT
      # Wait for cert-manager to be ready
      echo "Waiting for cert-manager CRDs to be available..."

      # Wait for the webhook to be ready first
      echo "Waiting for cert-manager webhook pod to be ready..."
      kubectl -n cert-manager wait --for=condition=ready pod -l app=webhook --timeout=120s

      # Try up to 10 times with increasing sleep between attempts
      for i in $(seq 1 10); do
        echo "Attempt $i to verify cert-manager CRDs..."

        # Check if the ClusterIssuer CRD exists
        if kubectl get crd clusterissuers.cert-manager.io > /dev/null 2>&1; then
          echo "ClusterIssuer CRD found!"
          exit 0
        fi

        # Increase wait time with each attempt
        sleep_time=$((i * 5))
        echo "CRDs not found yet, waiting $sleep_time seconds..."
        sleep $sleep_time
      done

      # If we get here, we've failed to find the CRDs
      echo "Failed to find cert-manager CRDs after multiple attempts"
      exit 1
    EOT
  }
}

# Note: ClusterIssuer is now managed outside of Terraform
# TODO: Automate the ClusterIssuer creation
# We've already created it manually with the setup_argocd.sh script

# Install ArgoCD
resource "helm_release" "argocd" {
  name       = "argocd"
  repository = "https://argoproj.github.io/argo-helm"
  chart      = "argo-cd"
  version    = "9.3.7"
  namespace  = kubernetes_namespace.argocd.metadata[0].name

  set {
    name  = "server.service.type"
    value = "ClusterIP"
  }

  set {
    name  = "server.ingress.enabled"
    value = "true"
  }

  set {
    name  = "server.ingress.hosts[0]"
    value = "argo.junv.cc"
  }

  set {
    name  = "server.ingress.ingressClassName"
    value = "nginx"
  }

  set {
    name  = "server.ingress.annotations.cert-manager\\.io/cluster-issuer"
    value = "letsencrypt-prod"
  }

  set {
    name  = "server.ingress.tls[0].hosts[0]"
    value = "argo.junv.cc"
  }

  set {
    name  = "server.ingress.tls[0].secretName"
    value = "argocd-server-tls"
  }

  set {
    name  = "server.extraArgs[0]"
    value = "--insecure"
  }

  set {
    name  = "server.insecure"
    value = "true"
  }

  depends_on = [
    helm_release.cert_manager,
    helm_release.ingress_nginx
  ]

  # Add timeout to ensure ArgoCD has enough time to install
  timeout = 900

  # Add retry logic in case of failure
  recreate_pods = true
}
