package handler

import (
	"bytes"
	"context"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"path/filepath"
	"testing"

	"codeberg.org/VARASYS/ZDDC/zddc/internal/config"
	"codeberg.org/VARASYS/ZDDC/zddc/internal/zddc"
)

// TestPutToIssuedAsUnelevatedNonAdminUserDenied reproduces the bitnest
// observation: an un-elevated user@bitnest.cc was able to PUT a markdown
// file inside archive/<party>/issued/<transmittal>/ even though the
// embedded defaults declare issued/ as WORM and the user is not in the
// document_controller role. Expectation: 403. If this test passes (i.e.
// 403), the bug is somewhere outside this path; if it fails (200 or
// similar), we've reproduced the bypass.
func TestPutToIssuedAsUnelevatedNonAdminUserDenied(t *testing.T) {
	root := t.TempDir()
	// Mirror bitnest's current root .zddc shape: user@bitnest.cc is in
	// admins (potential admin) but un-elevated — should NOT have admin
	// authority. Roles populate document_controller and project_team
	// (which matches *@bitnest.cc → user@bitnest.cc gets project_team:r
	// at project level via the embedded defaults).
	mustWriteHelper(t, filepath.Join(root, ".zddc"),
		"admins:\n  - user@bitnest.cc\n"+
			"roles:\n"+
			"  document_controller:\n    members: [alice@example.com, bob@example.com]\n"+
			"  project_team:\n    members: [\"*@example.com\", \"*@bitnest.cc\"]\n")

	// Materialise the exact path shape from the bitnest log entry.
	issuedDir := filepath.Join(root, "Project-1/archive/PartyA/issued/2025-09-21_A-FAC2-PM-DRW-0377 (RSB) - Test")
	if err := os.MkdirAll(issuedDir, 0o755); err != nil {
		t.Fatalf("mkdir issued: %v", err)
	}
	target := filepath.Join(issuedDir, "A-FAC1-EL-SPC-0469_0A (IFR) - Test.md")
	if err := os.WriteFile(target, []byte("# original\n"), 0o644); err != nil {
		t.Fatalf("seed target: %v", err)
	}
	zddc.InvalidateCache(root)

	cfg := config.Config{
		Root:          root,
		EmailHeader:   "X-Auth-Request-Email",
		MaxWriteBytes: 64 * 1024,
	}

	// Construct the PUT exactly as the markdown editor in browse would —
	// PUT to the file's URL with the modified body.
	u := &url.URL{Path: "/Project-1/archive/PartyA/issued/2025-09-21_A-FAC2-PM-DRW-0377 (RSB) - Test/A-FAC1-EL-SPC-0469_0A (IFR) - Test.md"}
	req := httptest.NewRequest(http.MethodPut, u.RequestURI(), bytes.NewReader([]byte("# modified by un-elevated user\n")))
	req.Header.Set("Content-Type", "text/markdown")

	// Critical: emulate ACLMiddleware's effect. user@bitnest.cc, elevation = false.
	ctx := context.WithValue(req.Context(), EmailKey, "user@bitnest.cc")
	ctx = context.WithValue(ctx, ElevatedKey, false)
	req = req.WithContext(ctx)

	rec := httptest.NewRecorder()
	ServeFileAPI(cfg, rec, req)

	if rec.Code == http.StatusOK || rec.Code == http.StatusCreated {
		t.Errorf("BUG REPRODUCED — un-elevated non-doc-controller wrote to WORM issued/: status=%d body=%q", rec.Code, rec.Body.String())
	} else if rec.Code != http.StatusForbidden {
		t.Errorf("status=%d (want 403); body=%q", rec.Code, rec.Body.String())
	}

	// Bytes-on-disk check too: even if the response says forbidden, the
	// write must NOT have landed.
	gotBytes, _ := os.ReadFile(target)
	if string(gotBytes) != "# original\n" {
		t.Errorf("file bytes mutated: got %q, want original", string(gotBytes))
	}
}
