package apps

import (
	"path/filepath"
	"testing"
)

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

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

		// classifier: working/, staging/, archive/<party>/incoming/ and subtrees
		{root, "classifier", false},
		{root + "/Project-A", "classifier", false},
		{root + "/Project-A/working", "classifier", true},
		{root + "/Project-A/working/deep/nested/path", "classifier", true},
		{root + "/Project-A/staging", "classifier", true},
		{root + "/Project-A/staging/2026-06-15_x (DFT) - y", "classifier", true},
		{root + "/Project-A/archive/ACME/incoming", "classifier", true},
		{root + "/Project-A/archive/ACME/incoming/sub", "classifier", true},
		{root + "/Project-A/archive/ACME/received", "classifier", false},
		{root + "/Project-A/archive/ACME/issued", "classifier", false},
		{root + "/Project-A/archive/ACME/mdl", "classifier", false},
		{root + "/Project-A/some-other-folder", "classifier", false},

		// mdedit: working/ only (review responses live in working/<rs-name>/)
		{root + "/Project-A/working", "mdedit", true},
		{root + "/Project-A/working/sub", "mdedit", true},
		{root + "/Project-A/staging", "mdedit", false},
		{root + "/Project-A/archive/ACME/incoming", "mdedit", false},

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

		// case-fold: any case of canonical names matches
		{root + "/Project-A/Working", "mdedit", true},
		{root + "/Project-A/WORKING", "mdedit", true},
		{root + "/Project-A/Staging", "transmittal", true},
		{root + "/Project-A/STAGING", "transmittal", true},
		{root + "/Project-A/archive/ACME/Incoming", "classifier", true},
		{root + "/Project-A/Archive/ACME/incoming", "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
	}{
		// At the deployment root itself, no default tool — landing handles
		// the project picker via a separate path.
		{root, ""},
		// Bare project root: no default. Trailing-slash URL serves browse;
		// no-slash falls through to the redirect.
		{root + "/Project-A", ""},
		// Canonical project-root folders.
		{root + "/Project-A/working", "mdedit"},
		{root + "/Project-A/working/alice@example.com", "mdedit"},
		{root + "/Project-A/working/2026-06-15_x (DFT) - y", "mdedit"},
		{root + "/Project-A/staging", "transmittal"},
		{root + "/Project-A/staging/2026-06-15_x (DFT) - y", "transmittal"},
		// archive: at the archive root, party folders default to archive.
		// Per-party subfolders override per their function:
		//   incoming → classifier (the bulk-rename workflow)
		//   received / issued     → archive (WORM record browser)
		{root + "/Project-A/archive", "archive"},
		{root + "/Project-A/archive/Acme", "archive"},
		{root + "/Project-A/archive/Acme/incoming", "classifier"},
		{root + "/Project-A/archive/Acme/issued", "archive"},
		{root + "/Project-A/archive/Acme/received", "archive"},
		// mdl wins over the broader archive rule.
		{root + "/Project-A/archive/Acme/mdl", "tables"},
		{root + "/Project-A/archive/Acme/mdl/anything-deeper", "tables"},
		// reviewing/ is virtual but mdedit is wired as the default
		// tool; the polyfill follows the listing's canonical URLs
		// into archive/ and staging/ for the actual files.
		{root + "/Project-A/reviewing", "mdedit"},
		{root + "/Project-A/reviewing/123-EM-SUB-0001", "mdedit"},
		// Random non-canonical folder names → no default.
		{root + "/Project-A/scratch", ""},
		// Case-fold on canonical names.
		{root + "/Project-A/Working", "mdedit"},
		{root + "/Project-A/STAGING", "transmittal"},
		{root + "/Project-A/Archive/Acme/MDL", "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)
			}
		})
	}
}
