#!/usr/bin/env bash
set -euo pipefail

REPO_ROOT=$(unset CDPATH && cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)
TMPDIR="$REPO_ROOT/deployments/.ops-server-deploy-new-region-test.$$"
mkdir -p "$TMPDIR"
trap 'rm -rf "$TMPDIR"' EXIT

mkdir -p \
  "$TMPDIR/deployments/infra-v2/ops-server" \
  "$TMPDIR/deployments/infra-v2/ops-server/variants" \
  "$TMPDIR/deployments/lib"

cp "$REPO_ROOT/deployments/infra-v2/ops-server/deploy-new-region.sh" \
  "$TMPDIR/deployments/infra-v2/ops-server/deploy-new-region.sh"
cp "$REPO_ROOT/deployments/infra-v2/ops-server/variants/aws-values-tmpl.yaml" \
  "$TMPDIR/deployments/infra-v2/ops-server/variants/aws-values-tmpl.yaml"
cp "$REPO_ROOT/deployments/infra-v2/ops-server/variants/byoc-aws-values-tmpl.yaml" \
  "$TMPDIR/deployments/infra-v2/ops-server/variants/byoc-aws-values-tmpl.yaml"
cp "$REPO_ROOT/deployments/infra-v2/ops-server/variants/azure-byoc-values-tmpl.yaml" \
  "$TMPDIR/deployments/infra-v2/ops-server/variants/azure-byoc-values-tmpl.yaml"
cp "$REPO_ROOT/deployments/lib/lib.sh" "$TMPDIR/deployments/lib/lib.sh"

cat >"$TMPDIR/azure-byoc-input.json" <<'EOF'
{
  "imageRegistry": "customer.azurecr.io",
  "fluxRegistry": "",
  "regionalServerRoleARN": "00000000-0000-0000-0000-000000000111",
  "subscriptionID": "sub-123",
  "hostedZoneName": "o11y.example.com",
  "wafACLARN": "/subscriptions/sub-123/resourceGroups/rg-o11y/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/rs-api",
  "byoc": true
}
EOF
jq -c . "$TMPDIR/azure-byoc-input.json" | jq -R . >"$TMPDIR/azure-byoc-workflow-input.json"

bash "$TMPDIR/deployments/infra-v2/ops-server/deploy-new-region.sh" \
  azure dev eastus eastus-byoc aks-customer "$TMPDIR/azure-byoc-workflow-input.json"

azure_values="$TMPDIR/deployments/infra-v2/ops-server/envs/dev/regional-azure-eastus-byoc.yaml"
test -f "$azure_values"
! grep -q 'TMPL_' "$azure_values"
test "$(yq eval '.global.registry' "$azure_values")" = "customer.azurecr.io"
test "$(yq eval '.global.region' "$azure_values")" = "eastus"
test "$(yq eval '.global.logicalRegion' "$azure_values")" = "eastus-byoc"
test "$(yq eval '.opsServer.config.vendor' "$azure_values")" = "azure"
test "$(yq eval '.opsServer.azure.subscriptionId' "$azure_values")" = "sub-123"
test "$(yq eval '.opsServer.azure.resourceGroup' "$azure_values")" = "aks-customer"
test "$(yq eval '.ingress.enabled' "$azure_values")" = "true"
test "$(yq eval '.ingress.className' "$azure_values")" = "azure-application-gateway"
test "$(yq eval '.ingress.annotations."appgw.ingress.kubernetes.io/health-probe-path"' "$azure_values")" = "/ops/api/v1/"
test "$(yq eval '.ingress.annotations."appgw.ingress.kubernetes.io/waf-policy-for-path"' "$azure_values")" = "/subscriptions/sub-123/resourceGroups/rg-o11y/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/rs-api"
test "$(yq eval '.ingress.annotations."cert-manager.io/acme-challenge-type"' "$azure_values")" = "http01"
test "$(yq eval '.ingress.annotations."cert-manager.io/cluster-issuer"' "$azure_values")" = "letsencrypt-for-o11y"
test "$(yq eval '.ingress.hosts[0].host' "$azure_values")" = "www.rs.eastus-byoc.azure.o11y.example.com"
test "$(yq eval '.ingress.hosts[0].paths[0].path' "$azure_values")" = "/ops/api/v1/"
test "$(yq eval '.ingress.hosts[0].paths[0].pathType' "$azure_values")" = "Prefix"
test "$(yq eval '.ingress.hosts[0].paths[0].port' "$azure_values")" = "8180"
test "$(yq eval '.ingress.tls[0].hosts[0]' "$azure_values")" = "www.rs.eastus-byoc.azure.o11y.example.com"
test "$(yq eval '.ingress.tls[0].secretName' "$azure_values")" = "ops-server-certs"
test "$(yq eval '.serviceAccount.annotations."azure.workload.identity/client-id"' "$azure_values")" = "00000000-0000-0000-0000-000000000111"
test "$(yq eval '.flux.repo.registry' "$azure_values")" = "customer.azurecr.io"
test "$(yq eval '.flux.repo.provider' "$azure_values")" = "azure"
test "$(yq eval '.sourceController.image.repository' "$azure_values")" = "customer.azurecr.io/third-party/fluxcd/source-controller"
test "$(yq eval '.helmController.image.repository' "$azure_values")" = "customer.azurecr.io/third-party/fluxcd/helm-controller"

rendered="$TMPDIR/rendered-ops-server.yaml"
helm template ops-server "$REPO_ROOT/deployments/charts/ops-server" \
  -n ops-system \
  -f "$azure_values" >"$rendered"

test "$(yq eval 'select(.kind == "Ingress" and .metadata.name == "ops-server") | .metadata.namespace' "$rendered")" = "ops-system"
test "$(yq eval 'select(.kind == "Ingress" and .metadata.name == "ops-server") | .spec.ingressClassName' "$rendered")" = "azure-application-gateway"
test "$(yq eval 'select(.kind == "Ingress" and .metadata.name == "ops-server") | .metadata.annotations."appgw.ingress.kubernetes.io/health-probe-path"' "$rendered")" = "/ops/api/v1/"
test "$(yq eval 'select(.kind == "Ingress" and .metadata.name == "ops-server") | .metadata.annotations."appgw.ingress.kubernetes.io/waf-policy-for-path"' "$rendered")" = "/subscriptions/sub-123/resourceGroups/rg-o11y/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/rs-api"
test "$(yq eval 'select(.kind == "Ingress" and .metadata.name == "ops-server") | .metadata.annotations."cert-manager.io/cluster-issuer"' "$rendered")" = "letsencrypt-for-o11y"
test "$(yq eval 'select(.kind == "Ingress" and .metadata.name == "ops-server") | .spec.tls[0].hosts[0]' "$rendered")" = "www.rs.eastus-byoc.azure.o11y.example.com"
test "$(yq eval 'select(.kind == "Ingress" and .metadata.name == "ops-server") | .spec.tls[0].secretName' "$rendered")" = "ops-server-certs"
test "$(yq eval 'select(.kind == "Ingress" and .metadata.name == "ops-server") | .spec.rules[0].host' "$rendered")" = "www.rs.eastus-byoc.azure.o11y.example.com"
test "$(yq eval 'select(.kind == "Ingress" and .metadata.name == "ops-server") | .spec.rules[0].http.paths[0].path' "$rendered")" = "/ops/api/v1/"
test "$(yq eval 'select(.kind == "Ingress" and .metadata.name == "ops-server") | .spec.rules[0].http.paths[0].pathType' "$rendered")" = "Prefix"
test "$(yq eval 'select(.kind == "Ingress" and .metadata.name == "ops-server") | .spec.rules[0].http.paths[0].backend.service.port.number' "$rendered")" = "8180"
test "$(yq eval 'select(.kind == "ServiceAccount" and .metadata.name == "ops-server") | .metadata.annotations."azure.workload.identity/client-id"' "$rendered")" = "00000000-0000-0000-0000-000000000111"
test "$(yq eval 'select(.kind == "Deployment" and .metadata.name == "ops-server") | .spec.template.metadata.labels."azure.workload.identity/use"' "$rendered")" = "true"
test "$(yq eval 'select(.kind == "Deployment" and .metadata.name == "ops-server") | .spec.template.spec.containers[] | select(.name == "ops-server") | .env[] | select(.name == "AZURE_SUBSCRIPTION_ID") | .value' "$rendered")" = "sub-123"
test "$(yq eval 'select(.kind == "Deployment" and .metadata.name == "ops-server") | .spec.template.spec.containers[] | select(.name == "ops-server") | .env[] | select(.name == "AZURE_RESOURCE_GROUP") | .value' "$rendered")" = "aks-customer"
test "$(yq eval 'select(.kind == "Deployment" and .metadata.name == "ops-server") | .spec.template.spec.containers[] | select(.name == "source-controller") | .image' "$rendered")" = "customer.azurecr.io/third-party/fluxcd/source-controller:v1.7.4"
test "$(yq eval 'select(.kind == "Deployment" and .metadata.name == "ops-server") | .spec.template.spec.containers[] | select(.name == "helm-controller") | .image' "$rendered")" = "customer.azurecr.io/third-party/fluxcd/helm-controller:v1.5.4"
test "$(yq eval 'select(.kind == "HelmRepository" and .metadata.name == "o11y-helm-repo") | .metadata.namespace' "$rendered")" = "ops-system"
test "$(yq eval 'select(.kind == "HelmRepository" and .metadata.name == "o11y-helm-repo") | .spec.url' "$rendered")" = "oci://customer.azurecr.io/observability-charts"
test "$(yq eval 'select(.kind == "HelmRepository" and .metadata.name == "o11y-helm-repo") | .spec.provider' "$rendered")" = "azure"

cat >"$TMPDIR/azure-standard-input.json" <<'EOF'
{
  "byoc": false
}
EOF

bash "$TMPDIR/deployments/infra-v2/ops-server/deploy-new-region.sh" \
  azure dev eastus eastus-standard aks-standard "$TMPDIR/azure-standard-input.json"
test ! -f "$TMPDIR/deployments/infra-v2/ops-server/envs/dev/regional-azure-eastus-standard.yaml"

cat >"$TMPDIR/azure-missing-subscription.json" <<'EOF'
{
  "imageRegistry": "customer.azurecr.io",
  "regionalServerRoleARN": "00000000-0000-0000-0000-000000000111",
  "byoc": true
}
EOF

if bash "$TMPDIR/deployments/infra-v2/ops-server/deploy-new-region.sh" \
  azure dev eastus eastus-missing-sub aks-customer "$TMPDIR/azure-missing-subscription.json" 2>"$TMPDIR/missing-subscription.err"; then
  echo "azure byoc ops-server generation should require subscriptionID" >&2
  exit 1
fi
grep -q "subscriptionID must be provided" "$TMPDIR/missing-subscription.err"

cat >"$TMPDIR/aws-byoc-input.json" <<'EOF'
{
  "imageRegistry": "123456789012.dkr.ecr.us-west-2.amazonaws.com",
  "regionalServerRoleARN": "arn:aws:iam::123456789012:role/o11y-control-plane",
  "byoc": true
}
EOF

bash "$TMPDIR/deployments/infra-v2/ops-server/deploy-new-region.sh" \
  aws dev us-west-2 us-west-2-byoc eks-customer "$TMPDIR/aws-byoc-input.json"

aws_values="$TMPDIR/deployments/infra-v2/ops-server/envs/dev/regional-aws-us-west-2-byoc.yaml"
test -f "$aws_values"
! grep -q 'TMPL_' "$aws_values"
test "$(yq eval '.opsServer.config.vendor' "$aws_values")" = "aws"
test "$(yq eval '.global.logicalRegion' "$aws_values")" = "us-west-2-byoc"
test "$(yq eval '.ingress.enabled' "$aws_values")" = "true"
test "$(yq eval '.ingress.className' "$aws_values")" = "alb"
test "$(yq eval '.ingress.annotations."alb.ingress.kubernetes.io/scheme"' "$aws_values")" = "internal"
test "$(yq eval '.opsServer.config.selfMonitorEndpoint' "$aws_values")" = "http://prometheus-operated.self-monitoring:9090"
test "$(yq eval '.serviceAccount.annotations."eks.amazonaws.com/role-arn"' "$aws_values")" = "arn:aws:iam::123456789012:role/o11y-control-plane"
test "$(yq eval '.flux.repo.registry' "$aws_values")" = "123456789012.dkr.ecr.us-west-2.amazonaws.com"
test "$(yq eval '.flux.repo.provider' "$aws_values")" = "aws"
test "$(yq eval '.opsServer.azure.subscriptionId // ""' "$aws_values")" = ""

echo "ops-server deploy-new-region tests passed"
