package catalogreconcile

import (
	"crypto/sha256"
	"encoding/hex"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func TestCatalogReconcilePublisherActivationIsPinnedAndOwnerScoped(t *testing.T) {
	root := filepath.Clean("..")
	reviewPath := filepath.Join(root, ".github", "workflows", "codex-review.yml")
	review, err := os.ReadFile(reviewPath)
	if err != nil {
		t.Fatal(err)
	}
	reviewText := string(review)
	if !strings.Contains(reviewText, "auto-merge: 'false'") || strings.Contains(reviewText, "auto-merge: 'true'") {
		t.Fatal("push-only Catalog publication requires review and merge to have separate owners")
	}
	for _, forbidden := range []string{"packages: write", "id-token: write", "NEXUSCRM_DEPLOY_KEY", "NEXUSCRM_CONNECTORS_DEPLOY_KEY", "NEXUSCRM_CONTRACT_DEPLOY_KEY"} {
		if strings.Contains(reviewText, forbidden) {
			t.Errorf("Catalog review/merge plane contains publisher authority %q", forbidden)
		}
	}

	activePath := filepath.Join(root, ".github", "workflows", "publish-catalog-reconcile-image.yml")
	active, err := os.ReadFile(activePath)
	if err != nil {
		t.Fatal(err)
	}
	activeText := string(active)
	for _, required := range []string{
		"name: publish-catalog-reconcile-image",
		"push:\n    branches: [main]",
		"permissions: {}",
		"contents: read",
		"packages: write",
		"id-token: write",
		"needs: validate-runtimework",
		"name: Validate Runtime Worker ownership without publication authority",
		"go test ./runtimework -count=1",
		"go test -race ./runtimework -count=1",
		"go vet ./runtimework",
		"uses: pingcap-inc/nexuscrm-controlplane/.github/workflows/trusted-publish-catalog-reconcile-image.yml@4c215f761786f4ae66a8a2a4b834c30e601abfd4",
		"NEXUSCRM_DEPLOY_KEY: ${{ secrets.NEXUSCRM_DEPLOY_KEY }}",
		"NEXUSCRM_CONNECTORS_DEPLOY_KEY: ${{ secrets.NEXUSCRM_CONNECTORS_DEPLOY_KEY }}",
		"NEXUSCRM_CONTRACT_DEPLOY_KEY: ${{ secrets.NEXUSCRM_CONTRACT_DEPLOY_KEY }}",
	} {
		if !strings.Contains(activeText, required) {
			t.Errorf("active Catalog publisher missing %q", required)
		}
	}
	for _, forbidden := range []string{"workflow_dispatch:", "pull_request:", "actions/attest", "CROSS_REPO_READ_TOKEN", ":latest"} {
		if strings.Contains(activeText, forbidden) {
			t.Errorf("active Catalog caller contains forbidden trigger, service, credential, or tag %q", forbidden)
		}
	}
	runtimeWorkValidation := strings.Index(activeText, "  validate-runtimework:")
	publish := strings.Index(activeText, "  publish:")
	if runtimeWorkValidation < 0 || publish <= runtimeWorkValidation {
		t.Fatal("Runtime Worker validation must complete before the immutable publisher")
	}
	if strings.Contains(activeText[publish:], "\n    with:") {
		t.Fatal("legacy main publisher must remain able to call the reusable workflow without source inputs")
	}
	for _, forbidden := range []string{"packages: write", "id-token: write"} {
		if strings.Contains(activeText[runtimeWorkValidation:publish], forbidden) {
			t.Errorf("Runtime Worker validation contains publication authority %q", forbidden)
		}
	}
	workflowPath := filepath.Join(root, ".github", "workflows", "trusted-publish-catalog-reconcile-image.yml")
	workflow, err := os.ReadFile(workflowPath)
	if err != nil {
		t.Fatal(err)
	}
	text := string(workflow)
	for _, required := range []string{
		"workflow_call:",
		"source_ref:\n        description: Optional exact source branch ref; omit with source_sha for the legacy main-push path\n        required: false\n        default: \"\"\n        type: string",
		"source_sha:\n        description: Optional exact source branch head; omit with source_ref for the legacy main-push path\n        required: false\n        default: \"\"\n        type: string",
		"SOURCE_REF: ${{ inputs.source_ref || github.ref }}",
		"SOURCE_SHA: ${{ inputs.source_sha || github.sha }}",
		"ref: ${{ env.SOURCE_SHA }}",
		"persist-credentials: false",
		`GOFLAGS: "-mod=readonly"`,
		"permissions: {}",
		"packages: write",
		"id-token: write",
		"group: publish-catalog-reconcile-image-${{ inputs.source_sha || 'main' }}",
		"Select legacy or explicit Catalog source",
		`if test -z "$INPUT_SOURCE_REF" && test -z "$INPUT_SOURCE_SHA"; then`,
		`echo 'source_mode=legacy' >> "$GITHUB_OUTPUT"`,
		`elif test -n "$INPUT_SOURCE_REF" && test -n "$INPUT_SOURCE_SHA"; then`,
		`echo 'source_mode=explicit' >> "$GITHUB_OUTPUT"`,
		"source_ref and source_sha must either both be supplied or both be empty",
		`test "$SOURCE_REF" = "$GITHUB_REF"`,
		`test "$SOURCE_SHA" = "$GITHUB_SHA"`,
		"Bind the trusted main controller to one branch head",
		`fetch --no-tags origin "+$SOURCE_REF:refs/remotes/nexuscrm-controlplane/release-source"`,
		`test "$(git rev-parse refs/remotes/nexuscrm-controlplane/release-source)" = "$SOURCE_SHA"`,
		"workflow_dispatch) caller=pingcap-inc/nexuscrm-controlplane/.github/workflows/publish-catalog-reconcile-dev-image.yml",
		"IMAGE_NAME: ghcr.io/pingcap-inc/nexuscrm-controlplane-catalog-reconcile",
		"tags: ${{ env.IMAGE_NAME }}:pending-${{ env.SOURCE_SHA }}-${{ github.run_id }}-${{ github.run_attempt }}",
		"provenance: mode=max",
		"sbom: true",
		"org.opencontainers.image.revision",
		"NEXUSCRM_DEPLOY_KEY is required",
		"NEXUSCRM_CONNECTORS_DEPLOY_KEY is required",
		"NEXUSCRM_CONTRACT_DEPLOY_KEY is required",
		"Verify private credential cleanup",
		"go test ./catalogapp ./catalogreconcile ./cmd/catalog-reconcile -count=1",
		"go test -race ./catalogreconcile ./cmd/catalog-reconcile -count=1",
		"go vet ./catalogapp ./catalogreconcile ./cmd/catalog-reconcile",
		"git diff --exit-code",
		`git status --porcelain=v1 --untracked-files=all`,
		"CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build",
		`$RUNNER_TEMP/catalog-reconcile-image`,
		"context: ${{ runner.temp }}/catalog-reconcile-image",
		"platforms: linux/amd64",
		`--data-urlencode "scope=repository:$repository:pull,push"`,
		`if [ "$status" = 200 ]; then`,
		`elif [ "$status" = 404 ]; then`,
		"refusing to publish",
		"aws-actions/configure-aws-credentials@d979d5b3a71173a29b74b5b88418bfda9437d885",
		"Verify immutable reusable-workflow OIDC identity",
		"cosign attest --yes",
		"cosign verify-attestation",
		"Commit independently verified Catalog source tag",
		"Reverify immutable existing release without signing authority",
	} {
		if !strings.Contains(text, required) {
			t.Errorf("publication workflow missing %q", required)
		}
	}
	if strings.Contains(text, `if docker buildx imagetools inspect "${image_tag}"`) {
		t.Fatal("publisher again treats an ambiguous registry failure as tag absence")
	}
	for _, forbidden := range []string{
		"ref: ${{ inputs.source_sha }}",
		"pending-${{ inputs.source_sha }}",
		"SOURCE_SHA=${{ inputs.source_sha }}",
	} {
		if strings.Contains(text, forbidden) {
			t.Errorf("optional source SHA bypasses its legacy fallback in %q", forbidden)
		}
	}
	for _, forbidden := range []string{
		"workflow_dispatch:",
		"actions/attest",
		"gh attestation",
		"CROSS_REPO_READ_TOKEN",
		":latest",
		"pull_request:",
		"workflow_run:",
		"replace github.com/",
	} {
		if strings.Contains(text, forbidden) {
			t.Errorf("inactive trusted publisher contains forbidden activation, unavailable service, or mutable path %q", forbidden)
		}
	}
	if strings.Count(text, "git diff --exit-code") < 2 || strings.Count(text, "git status --porcelain=v1 --untracked-files=all") < 2 {
		t.Fatal("exact-source publication must prove a clean source tree after validation and after the out-of-tree build")
	}
	if got := strings.Count(text, `io.nexuscrm.signer.workflow=$GITHUB_WORKFLOW_REF`); got != 3 {
		t.Fatalf("caller-workflow signer compatibility checks = %d, want 3", got)
	}
	fetch := strings.Index(text, "- name: Fetch exact private module graph")
	cleanup := strings.Index(text, "- name: Verify private credential cleanup")
	testCommand := strings.Index(text, "- name: Validate exact Catalog source without publication authority")
	registry := strings.Index(text, "- name: Resolve existing immutable SHA tag")
	if fetch < 0 || cleanup <= fetch || testCommand <= cleanup || registry <= testCommand {
		t.Fatal("private dependency fetch, cleanup, exact-source validation and registry access must remain strictly ordered")
	}
	candidate := strings.Index(text, "  candidate:")
	sign := strings.Index(text, "  sign:")
	verifyNew := strings.Index(text, "  verify-new:")
	commit := strings.Index(text, "  commit-release:")
	verifyExisting := strings.Index(text, "  verify-existing:")
	if candidate < 0 || sign <= candidate || verifyNew <= sign || commit <= verifyNew || verifyExisting <= commit {
		t.Fatal("trusted publisher must keep candidate, isolated signer, independent verification, stable-tag commit, and verify-only reuse ordered")
	}
	signer := text[sign:verifyNew]
	if strings.Contains(signer, "actions/checkout") || strings.Contains(signer, "NEXUSCRM_DEPLOY_KEY") {
		t.Fatal("signer must not checkout or execute caller source and must not receive private source credentials")
	}
	for _, required := range []string{
		"push)\n              workflow_name=publish-catalog-reconcile-image",
		"workflow_dispatch)\n              workflow_name=publish-catalog-reconcile-dev-image",
		"caller=pingcap-inc/nexuscrm-controlplane/.github/workflows/publish-catalog-reconcile-dev-image.yml",
		`test "$GITHUB_WORKFLOW" = "$workflow_name"`,
		`test "$GITHUB_WORKFLOW_REF" = "$caller@$GITHUB_REF"`,
	} {
		if !strings.Contains(signer, required) {
			t.Errorf("isolated signer lost event-bound caller identity %q", required)
		}
	}
	for _, forbidden := range []string{
		`test "$GITHUB_WORKFLOW" = publish-catalog-reconcile-image`,
		`test "$GITHUB_WORKFLOW_REF" = pingcap-inc/nexuscrm-controlplane/.github/workflows/publish-catalog-reconcile-image.yml@refs/heads/main`,
	} {
		if strings.Contains(signer, forbidden) {
			t.Errorf("isolated signer hard-codes push identity %q", forbidden)
		}
	}
	if strings.Count(text, "docker buildx imagetools create --tag") != 1 || !strings.Contains(text[commit:verifyExisting], "docker buildx imagetools create --tag") {
		t.Fatal("only the post-verification commit job may create the stable source tag")
	}

	policyPath := filepath.Join(root, "release", "catalog-reconcile-image-signing-policy.json")
	policy, err := os.ReadFile(policyPath)
	if err != nil {
		t.Fatal(err)
	}
	policyText := string(policy)
	for _, required := range []string{
		`"publisher_state": "active"`,
		`"owner_repository": "pingcap-inc/nexuscrm-controlplane"`,
		`"repository_id": "1279604400"`,
		`"image_repository": "ghcr.io/pingcap-inc/nexuscrm-controlplane-catalog-reconcile"`,
		`"aws_role_arn": "arn:aws:iam::604175033442:role/nexuscrm-controlplane-catalog-reconcile-publisher"`,
		`"kms_key_arn": "arn:aws:kms:us-west-2:604175033442:key/38698148-faea-456a-adff-450e687ba3ed"`,
		`"public_key_sha256": "sha256:829927b5b4ce3426e0096865dac7eec9b27be220fdd95458a53fce12c86cfe4a"`,
		`"trusted_workflow_ref": "pingcap-inc/nexuscrm-controlplane/.github/workflows/trusted-publish-catalog-reconcile-image.yml@4c215f761786f4ae66a8a2a4b834c30e601abfd4"`,
	} {
		if !strings.Contains(policyText, required) {
			t.Errorf("Catalog signing policy missing %q", required)
		}
	}
	publicKey, err := os.ReadFile(filepath.Join(root, "release", "catalog-reconcile-image-signing-public-key.pem"))
	if err != nil {
		t.Fatal(err)
	}
	if !strings.HasPrefix(string(publicKey), "-----BEGIN PUBLIC KEY-----\n") || !strings.HasSuffix(string(publicKey), "-----END PUBLIC KEY-----\n") {
		t.Fatal("Catalog verifier key is not a complete PEM public key")
	}
	keyDigest := sha256.Sum256(publicKey)
	if got, want := hex.EncodeToString(keyDigest[:]), "829927b5b4ce3426e0096865dac7eec9b27be220fdd95458a53fce12c86cfe4a"; got != want {
		t.Fatalf("Catalog verifier key digest = %s, want %s", got, want)
	}

	dockerfile, err := os.ReadFile(filepath.Join(root, "Dockerfile.catalog-reconcile"))
	if err != nil {
		t.Fatal(err)
	}
	for _, required := range []string{
		"FROM gcr.io/distroless/static-debian12:nonroot@sha256:",
		"org.opencontainers.image.revision=\"${SOURCE_SHA}\"",
		"ENTRYPOINT [\"/usr/local/bin/catalog-reconcile\"]",
	} {
		if !strings.Contains(string(dockerfile), required) {
			t.Errorf("Catalog reconcile Dockerfile missing %q", required)
		}
	}
}
