package apps

import (
	"path/filepath"
	"testing"
)

func TestAppAvailableAt(t *testing.T) {
	root := "/srv/zddc"
	cases := []struct {
		dir, app string
		want     bool
	}{
		// archive: everywhere (baseline)
		{root, "archive", true},
		{root + "/Project-A", "archive", true},
		{root + "/Project-A/working/ACME", "archive", true},
		{root + "/Project-A/some-other-folder", "archive", true},

		// landing: only at root
		{root, "landing", true},
		{root + "/Project-A", "landing", false},

		// classifier: the inbound/draft workspace peers (incoming/working/staging)
		{root, "classifier", false},
		{root + "/Project-A", "classifier", false},
		{root + "/Project-A/working/ACME", "classifier", true},
		{root + "/Project-A/working/ACME/deep/nested/path", "classifier", true},
		{root + "/Project-A/staging/ACME", "classifier", true},
		{root + "/Project-A/staging/ACME/2026-06-15_x (DFT) - y", "classifier", true},
		{root + "/Project-A/incoming/ACME", "classifier", true},
		{root + "/Project-A/incoming/ACME/sub", "classifier", true},
		{root + "/Project-A/reviewing/ACME", "classifier", false},
		{root + "/Project-A/archive/ACME/received", "classifier", false},
		{root + "/Project-A/mdl/ACME", "classifier", false},
		{root + "/Project-A/some-other-folder", "classifier", false},

		// browse: universal (baseline)
		{root + "/Project-A/working/ACME", "browse", true},
		{root + "/Project-A/staging/ACME", "browse", true},
		{root + "/Project-A/incoming/ACME", "browse", true},

		// transmittal: the staging peer only
		{root + "/Project-A/staging/ACME", "transmittal", true},
		{root + "/Project-A/staging/ACME/sub", "transmittal", true},
		{root + "/Project-A/working/ACME", "transmittal", false},
		{root + "/Project-A/archive/ACME/issued", "transmittal", false},

		// tables: the register peers
		{root + "/Project-A/mdl/ACME", "tables", true},
		{root + "/Project-A/rsk/ACME", "tables", true},
		{root + "/Project-A/ssr", "tables", true},

		// case-fold: any case of a peer name matches
		{root + "/Project-A/Staging/ACME", "transmittal", true},
		{root + "/Project-A/STAGING/ACME", "transmittal", true},
		{root + "/Project-A/Incoming/ACME", "classifier", true},

		// unknown app
		{root + "/Project-A", "weird", false},
	}
	for _, tc := range cases {
		t.Run(tc.app+"@"+tc.dir, func(t *testing.T) {
			got := AppAvailableAt(root, filepath.Clean(tc.dir), tc.app)
			if got != tc.want {
				t.Errorf("AppAvailableAt(%q, %q) = %v, want %v", tc.dir, tc.app, got, tc.want)
			}
		})
	}
}

func TestDefaultAppAt(t *testing.T) {
	root := "/srv/zddc"
	cases := []struct {
		dir  string
		want string
	}{
		// Deployment root + bare project root: no default tool.
		{root, ""},
		{root + "/Project-A", ""},
		// Top-level peers.
		{root + "/Project-A/working", "browse"},
		{root + "/Project-A/staging", "transmittal"},
		{root + "/Project-A/reviewing", "browse"},
		{root + "/Project-A/incoming", "classifier"},
		{root + "/Project-A/ssr", "tables"},
		{root + "/Project-A/mdl", "tables"},
		{root + "/Project-A/rsk", "tables"},
		// Per-party subdirs inherit the peer default.
		{root + "/Project-A/working/Acme", "browse"},
		{root + "/Project-A/working/Acme/2026-06-15_x (DFT) - y", "browse"},
		{root + "/Project-A/staging/Acme", "transmittal"},
		{root + "/Project-A/incoming/Acme", "classifier"},
		{root + "/Project-A/mdl/Acme", "tables"},
		{root + "/Project-A/mdl/Acme/anything-deeper", "tables"},
		{root + "/Project-A/rsk/Acme", "tables"},
		// The committed record: archive subtree → archive tool.
		{root + "/Project-A/archive", "archive"},
		{root + "/Project-A/archive/Acme", "archive"},
		{root + "/Project-A/archive/Acme/received", "archive"},
		{root + "/Project-A/archive/Acme/issued", "archive"},
		// Random non-canonical folder names → no default.
		{root + "/Project-A/scratch", ""},
		// Case-fold on peer names.
		{root + "/Project-A/Working/Acme", "browse"},
		{root + "/Project-A/STAGING/Acme", "transmittal"},
		{root + "/Project-A/MDL/Acme", "tables"},
	}
	for _, tc := range cases {
		t.Run(tc.dir, func(t *testing.T) {
			if got := DefaultAppAt(root, tc.dir); got != tc.want {
				t.Errorf("DefaultAppAt(%q) = %q, want %q", tc.dir, got, tc.want)
			}
		})
	}
}
