package zddc

import (
	"os"
	"path/filepath"
	"testing"
)

// TestWormZoneGrant_EmbeddedConvention — archive/<party>/received and
// issued carry `worm: []` in defaults.zddc.yaml, so any path under
// those folders is a WORM zone (inWorm=true) with no create-capable
// principals (grant=0). Other paths are not WORM zones.
func TestWormZoneGrant_EmbeddedConvention(t *testing.T) {
	resetCache()
	root := t.TempDir()

	cases := []struct {
		path       string
		wantInWorm bool
	}{
		{filepath.Join(root, "Proj", "archive", "Acme", "received"), true},
		{filepath.Join(root, "Proj", "archive", "Acme", "issued"), true},
		{filepath.Join(root, "Proj", "archive", "Acme", "received", "2025-Q1"), true}, // deeper still WORM
		{filepath.Join(root, "Proj", "archive", "Acme", "incoming"), false},
		{filepath.Join(root, "Proj", "archive", "Acme", "mdl"), false},
		{filepath.Join(root, "Proj", "working"), false},
		{filepath.Join(root, "Proj", "staging"), false},
	}
	for _, tc := range cases {
		chain, err := EffectivePolicy(root, tc.path)
		if err != nil {
			t.Fatalf("EffectivePolicy(%q): %v", tc.path, err)
		}
		grant, inWorm := WormZoneGrant(chain, "anyone@example.com")
		if inWorm != tc.wantInWorm {
			t.Errorf("WormZoneGrant(%q): inWorm = %v, want %v", tc.path[len(root):], inWorm, tc.wantInWorm)
		}
		if inWorm && grant != 0 {
			t.Errorf("WormZoneGrant(%q): grant = %v, want 0 (embedded baseline names no controllers)", tc.path[len(root):], grant)
		}
	}
}

// TestWormZoneGrant_OperatorGrantsController — a deployment grants a
// document controller create-once by placing a .zddc with a `worm:`
// entry naming them at (or below) the WORM folder. That principal then
// gets {r, c} from WormZoneGrant; everyone else still gets 0.
func TestWormZoneGrant_OperatorGrantsController(t *testing.T) {
	resetCache()
	root := t.TempDir()
	issuedDir := filepath.Join(root, "Proj", "archive", "Acme", "issued")
	if err := os.MkdirAll(issuedDir, 0o755); err != nil {
		t.Fatal(err)
	}
	writeZddc(t, issuedDir, "worm:\n  - doc-control@example.com\n")

	chain, err := EffectivePolicy(root, issuedDir)
	if err != nil {
		t.Fatal(err)
	}
	g, inWorm := WormZoneGrant(chain, "doc-control@example.com")
	if !inWorm {
		t.Fatalf("inWorm = false, want true")
	}
	if g != VerbsRC {
		t.Errorf("controller grant = %v, want rc", g)
	}
	g2, _ := WormZoneGrant(chain, "rando@example.com")
	if g2 != 0 {
		t.Errorf("non-controller grant = %v, want 0", g2)
	}
}

// TestWormZoneGrant_GrantIsAlwaysRC — a worm: entry never confers
// more than {r, c} no matter what (the list form can't even express
// w/d, but verifying the constant the resolver uses).
func TestWormZoneGrant_GrantIsAlwaysRC(t *testing.T) {
	resetCache()
	root := t.TempDir()
	rec := filepath.Join(root, "Proj", "archive", "Acme", "received")
	if err := os.MkdirAll(rec, 0o755); err != nil {
		t.Fatal(err)
	}
	writeZddc(t, rec, "worm:\n  - x@example.com\n")
	chain, _ := EffectivePolicy(root, rec)
	g, _ := WormZoneGrant(chain, "x@example.com")
	if g != VerbsRC {
		t.Errorf("grant = %v (%s), want rc", g, g.String())
	}
}

// TestWormZoneGrant_GrantsUnionAcrossCascade — worm: entries at
// multiple cascade levels compose: a controller named at the party
// level plus one named at the received level both get rc inside
// received/.
func TestWormZoneGrant_GrantsUnionAcrossCascade(t *testing.T) {
	resetCache()
	root := t.TempDir()
	party := filepath.Join(root, "Proj", "archive", "Acme")
	rec := filepath.Join(party, "received")
	if err := os.MkdirAll(rec, 0o755); err != nil {
		t.Fatal(err)
	}
	writeZddc(t, party, "worm:\n  - alice@example.com\n")
	writeZddc(t, rec, "worm:\n  - bob@example.com\n")
	chain, _ := EffectivePolicy(root, rec)

	ga, inA := WormZoneGrant(chain, "alice@example.com")
	if !inA || ga != VerbsRC {
		t.Errorf("alice grant = %v inWorm=%v, want rc/true", ga, inA)
	}
	gb, _ := WormZoneGrant(chain, "bob@example.com")
	if gb != VerbsRC {
		t.Errorf("bob grant = %v, want rc", gb)
	}
}
