package kb

import (
	"bytes"
	"context"
	"encoding/base64"
	"encoding/json"
	"net/http"
	"strings"
	"testing"

	"github.com/go-git/go-git/v5/plumbing"
	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/internal/store/resource/repos"
)

func TestAGSHTTPRepositoryStorePublishesDetachedUADashboardCommit(t *testing.T) {
	var calls []string
	var treeBody map[string]any
	var commitBody map[string]any
	var refBody map[string]any
	entries := make([]map[string]any, 0)
	for path, content := range validTestUAPublishRequest().Files {
		entries = append(entries, map[string]any{"path": path, "mode": "100644", "type": "blob", "sha": plumbing.ComputeHash(plumbing.BlobObject, content).String()})
	}
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		calls = append(calls, r.Method+" "+r.URL.RequestURI())
		switch r.Method + " " + r.URL.Path {
		case "GET /api/v3/repos/org/repo/git/refs/heads/main":
			writeUATestJSON(w, http.StatusOK, map[string]any{"ref": "refs/heads/main", "object": map[string]any{"sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "type": "commit"}})
		case "GET /api/v3/repos/org/repo/git/commits/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":
			writeUATestJSON(w, http.StatusOK, map[string]any{"sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "tree": map[string]any{"sha": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}})
		case "POST /api/v3/repos/org/repo/git/blobs":
			var body struct {
				Content string `json:"content"`
			}
			require.NoError(t, json.NewDecoder(r.Body).Decode(&body))
			content, err := base64.StdEncoding.DecodeString(body.Content)
			require.NoError(t, err)
			writeUATestJSON(w, http.StatusCreated, map[string]any{"sha": plumbing.ComputeHash(plumbing.BlobObject, content).String()})
		case "POST /api/v3/repos/org/repo/git/trees":
			require.NoError(t, json.NewDecoder(r.Body).Decode(&treeBody))
			writeUATestJSON(w, http.StatusCreated, map[string]any{"sha": "cccccccccccccccccccccccccccccccccccccccc"})
		case "GET /api/v3/repos/org/repo/git/trees/cccccccccccccccccccccccccccccccccccccccc":
			writeUATestJSON(w, http.StatusOK, map[string]any{"sha": "cccccccccccccccccccccccccccccccccccccccc", "tree": []map[string]any{{"path": ".ua", "mode": "040000", "type": "tree", "sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}}})
		case "GET /api/v3/repos/org/repo/git/trees/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":
			writeUATestJSON(w, http.StatusOK, map[string]any{"sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "tree": entries})
		case "POST /api/v3/repos/org/repo/git/commits":
			require.NoError(t, json.NewDecoder(r.Body).Decode(&commitBody))
			writeUATestJSON(w, http.StatusCreated, map[string]any{"sha": "dddddddddddddddddddddddddddddddddddddddd"})
		case "GET /api/v3/repos/org/repo/git/commits/dddddddddddddddddddddddddddddddddddddddd":
			writeUATestJSON(w, http.StatusOK, map[string]any{"sha": "dddddddddddddddddddddddddddddddddddddddd", "tree": map[string]any{"sha": "cccccccccccccccccccccccccccccccccccccccc"}, "parents": []map[string]any{{"sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}}})
		case "POST /api/v3/repos/org/repo/git/refs":
			require.NoError(t, json.NewDecoder(r.Body).Decode(&refBody))
			writeUATestJSON(w, http.StatusCreated, map[string]any{"ref": refBody["ref"], "object": map[string]any{"sha": "dddddddddddddddddddddddddddddddddddddddd"}})
		case "GET /api/v3/repos/org/repo/git/refs/meshx/kb-dashboard/src-1/dddddddddddddddddddddddddddddddddddddddd":
			writeUATestJSON(w, http.StatusOK, map[string]any{"ref": "refs/meshx/kb-dashboard/src-1/dddddddddddddddddddddddddddddddddddddddd", "object": map[string]any{"sha": "dddddddddddddddddddddddddddddddddddddddd"}})
		default:
			http.Error(w, "unexpected", http.StatusNotFound)
		}
	})
	store := AGSHTTPRepositoryStore{Handler: handler, AuthorizationHeader: "Bearer internal"}
	result, err := store.PublishUADashboard(context.Background(), UADashboardRepositoryPublishRequest{
		Repository: testUARepository(), SourceID: "src-1",
		Files: validTestUAPublishRequest().Files,
	})
	require.NoError(t, err)
	require.Equal(t, "dddddddddddddddddddddddddddddddddddddddd", result.CommitSHA)
	require.Equal(t, []string{
		"GET /api/v3/repos/org/repo/git/refs/heads/main",
		"GET /api/v3/repos/org/repo/git/commits/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		"POST /api/v3/repos/org/repo/git/blobs",
		"POST /api/v3/repos/org/repo/git/blobs",
		"POST /api/v3/repos/org/repo/git/blobs",
		"POST /api/v3/repos/org/repo/git/blobs",
		"POST /api/v3/repos/org/repo/git/blobs",
		"POST /api/v3/repos/org/repo/git/trees",
		"GET /api/v3/repos/org/repo/git/trees/cccccccccccccccccccccccccccccccccccccccc",
		"GET /api/v3/repos/org/repo/git/trees/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
		"POST /api/v3/repos/org/repo/git/commits",
		"GET /api/v3/repos/org/repo/git/commits/dddddddddddddddddddddddddddddddddddddddd",
		"POST /api/v3/repos/org/repo/git/refs",
		"GET /api/v3/repos/org/repo/git/refs/meshx/kb-dashboard/src-1/dddddddddddddddddddddddddddddddddddddddd",
	}, calls)
	require.Equal(t, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", treeBody["base_tree"])
	tree := treeBody["tree"].([]any)
	require.Len(t, tree, 6)
	deleteEntry := tree[0].(map[string]any)
	require.Equal(t, ".ua", deleteEntry["path"])
	require.Nil(t, deleteEntry["sha"])
	for _, rawEntry := range tree[1:] {
		entry := rawEntry.(map[string]any)
		require.NotEmpty(t, entry["sha"])
		require.NotContains(t, entry, "content")
	}
	require.Equal(t, []any{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, commitBody["parents"])
	require.Equal(t, "cccccccccccccccccccccccccccccccccccccccc", commitBody["tree"])
	require.Equal(t, "refs/meshx/kb-dashboard/src-1/dddddddddddddddddddddddddddddddddddddddd", refBody["ref"])
	require.Equal(t, "dddddddddddddddddddddddddddddddddddddddd", refBody["sha"])
	for _, call := range calls {
		require.False(t, strings.HasPrefix(call, "PATCH "), "default branch must not move")
	}
}

func TestAGSHTTPRepositoryStoreAcceptsExistingMatchingRetentionRef(t *testing.T) {
	handler := standardUAPublishHandler(t, func(w http.ResponseWriter, r *http.Request) bool {
		if r.Method == http.MethodPost && r.URL.Path == "/api/v3/repos/org/repo/git/refs" {
			http.Error(w, `{"message":"Reference already exists"}`, http.StatusUnprocessableEntity)
			return true
		}
		if r.Method == http.MethodGet && r.URL.Path == "/api/v3/repos/org/repo/git/refs/meshx/kb-dashboard/src-1/dddddddddddddddddddddddddddddddddddddddd" {
			writeUATestJSON(w, http.StatusOK, map[string]any{"ref": "refs/meshx/kb-dashboard/src-1/dddddddddddddddddddddddddddddddddddddddd", "object": map[string]any{"sha": "dddddddddddddddddddddddddddddddddddddddd"}})
			return true
		}
		return false
	})
	store := AGSHTTPRepositoryStore{Handler: handler, AuthorizationHeader: "Bearer internal"}
	_, err := store.PublishUADashboard(context.Background(), validTestUAPublishRequest())
	require.NoError(t, err)
}

func TestAGSHTTPRepositoryStoreRejectsConflictingRetentionRef(t *testing.T) {
	handler := standardUAPublishHandler(t, func(w http.ResponseWriter, r *http.Request) bool {
		if r.Method == http.MethodPost && r.URL.Path == "/api/v3/repos/org/repo/git/refs" {
			http.Error(w, `{"message":"Reference already exists"}`, http.StatusUnprocessableEntity)
			return true
		}
		if r.Method == http.MethodGet && r.URL.Path == "/api/v3/repos/org/repo/git/refs/meshx/kb-dashboard/src-1/dddddddddddddddddddddddddddddddddddddddd" {
			writeUATestJSON(w, http.StatusOK, map[string]any{"object": map[string]any{"sha": "9999999999999999999999999999999999999999"}})
			return true
		}
		return false
	})
	store := AGSHTTPRepositoryStore{Handler: handler, AuthorizationHeader: "Bearer internal"}
	_, err := store.PublishUADashboard(context.Background(), validTestUAPublishRequest())
	require.Error(t, err)
	require.NotContains(t, err.Error(), "Reference already exists")
}

func TestAGSHTTPRepositoryStoreRejectsMismatchedDashboardTrees(t *testing.T) {
	wantBlob := plumbing.ComputeHash(plumbing.BlobObject, []byte(`{}`)).String()
	tests := []struct {
		name       string
		root       map[string]any
		subtree    map[string]any
		mutateRoot func(map[string]any)
		mutateTree func(map[string]any)
	}{
		{name: "wrong root sha", mutateRoot: func(payload map[string]any) { payload["sha"] = "9999999999999999999999999999999999999999" }},
		{name: "truncated root", mutateRoot: func(payload map[string]any) { payload["truncated"] = true }},
		{name: "missing ua", mutateRoot: func(payload map[string]any) {
			payload["tree"] = []map[string]any{{"path": "README.md", "mode": "100644", "type": "blob", "sha": wantBlob}}
		}},
		{name: "duplicate ua", mutateRoot: func(payload map[string]any) {
			payload["tree"] = []map[string]any{{"path": ".ua", "mode": "040000", "type": "tree", "sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}, {"path": ".ua", "mode": "040000", "type": "tree", "sha": "ffffffffffffffffffffffffffffffffffffffff"}}
		}},
		{name: "wrong ua mode", mutateRoot: func(payload map[string]any) { payload["tree"].([]map[string]any)[0]["mode"] = "100644" }},
		{name: "wrong ua type", mutateRoot: func(payload map[string]any) { payload["tree"].([]map[string]any)[0]["type"] = "blob" }},
		{name: "wrong ua sha", mutateRoot: func(payload map[string]any) { payload["tree"].([]map[string]any)[0]["sha"] = "short" }},
		{name: "wrong subtree sha", mutateTree: func(payload map[string]any) { payload["sha"] = "9999999999999999999999999999999999999999" }},
		{name: "truncated subtree", mutateTree: func(payload map[string]any) { payload["truncated"] = true }},
		{name: "missing file", mutateTree: func(payload map[string]any) { payload["tree"] = []map[string]any{} }},
		{name: "extra file", mutateTree: func(payload map[string]any) {
			payload["tree"] = append(payload["tree"].([]map[string]any), map[string]any{"path": "extra.json", "mode": "100644", "type": "blob", "sha": wantBlob})
		}},
		{name: "duplicate file", mutateTree: func(payload map[string]any) {
			payload["tree"] = append(payload["tree"].([]map[string]any), payload["tree"].([]map[string]any)[0])
		}},
		{name: "wrong blob", mutateTree: func(payload map[string]any) {
			payload["tree"].([]map[string]any)[0]["sha"] = "9999999999999999999999999999999999999999"
		}},
		{name: "wrong file mode", mutateTree: func(payload map[string]any) { payload["tree"].([]map[string]any)[0]["mode"] = "100755" }},
		{name: "wrong file type", mutateTree: func(payload map[string]any) { payload["tree"].([]map[string]any)[0]["type"] = "tree" }},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			root := map[string]any{"sha": "cccccccccccccccccccccccccccccccccccccccc", "truncated": false, "tree": []map[string]any{{"path": ".ua", "mode": "040000", "type": "tree", "sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}}}
			entries := make([]map[string]any, 0, len(uaDashboardAllowedFiles))
			for path := range uaDashboardAllowedFiles {
				entries = append(entries, map[string]any{"path": path, "mode": "100644", "type": "blob", "sha": wantBlob})
			}
			subtree := map[string]any{"sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "truncated": false, "tree": entries}
			if test.mutateRoot != nil {
				test.mutateRoot(root)
			}
			if test.mutateTree != nil {
				test.mutateTree(subtree)
			}
			commitCalled := false
			handler := standardUAPublishHandler(t, func(w http.ResponseWriter, r *http.Request) bool {
				switch r.Method + " " + r.URL.Path {
				case "GET /api/v3/repos/org/repo/git/trees/cccccccccccccccccccccccccccccccccccccccc":
					writeUATestJSON(w, http.StatusOK, root)
					return true
				case "GET /api/v3/repos/org/repo/git/trees/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":
					writeUATestJSON(w, http.StatusOK, subtree)
					return true
				case "POST /api/v3/repos/org/repo/git/commits":
					commitCalled = true
				}
				return false
			})
			store := AGSHTTPRepositoryStore{Handler: handler, AuthorizationHeader: "Bearer internal"}
			_, err := store.PublishUADashboard(context.Background(), validTestUAPublishRequest())
			require.Error(t, err)
			require.False(t, commitCalled, "invalid tree must stop before commit creation")
		})
	}
}

func TestAGSHTTPRepositoryStoreRejectsDuplicateReplacingMissingDashboardFile(t *testing.T) {
	content := []byte(`{}`)
	blob := plumbing.ComputeHash(plumbing.BlobObject, content).String()
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.URL.Path {
		case "/api/v3/repos/org/repo/git/trees/cccccccccccccccccccccccccccccccccccccccc":
			writeUATestJSON(w, http.StatusOK, map[string]any{"sha": "cccccccccccccccccccccccccccccccccccccccc", "tree": []map[string]any{{"path": ".ua", "mode": "040000", "type": "tree", "sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}}})
		case "/api/v3/repos/org/repo/git/trees/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":
			writeUATestJSON(w, http.StatusOK, map[string]any{"sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "tree": []map[string]any{{"path": "knowledge-graph.json", "mode": "100644", "type": "blob", "sha": blob}, {"path": "knowledge-graph.json", "mode": "100644", "type": "blob", "sha": blob}}})
		default:
			http.NotFound(w, r)
		}
	})
	store := AGSHTTPRepositoryStore{Handler: handler}
	err := store.uaDashboardVerifyTree(context.Background(), uaRepositoryLocation{owner: "org", repo: "repo"}, "cccccccccccccccccccccccccccccccccccccccc", []string{"knowledge-graph.json", "domain-graph.json"}, map[string][]byte{"knowledge-graph.json": content, "domain-graph.json": content})
	require.Error(t, err)
}

func TestAGSHTTPRepositoryStoreReadsPinnedUADashboardFile(t *testing.T) {
	content := []byte(`{"graph":true}`)
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		require.Equal(t, "/api/v3/repos/org/repo/contents/.ua/knowledge-graph.json", r.URL.Path)
		require.Equal(t, "dddddddddddddddddddddddddddddddddddddddd", r.URL.Query().Get("ref"))
		writeUATestJSON(w, http.StatusOK, map[string]any{"type": "file", "path": ".ua/knowledge-graph.json", "sha": "ffffffffffffffffffffffffffffffffffffffff", "size": len(content), "encoding": "base64", "content": base64.StdEncoding.EncodeToString(content)})
	})
	store := AGSHTTPRepositoryStore{Handler: handler, AuthorizationHeader: "Bearer internal"}
	file, err := store.ReadUADashboardFile(context.Background(), UADashboardRepositoryFileRequest{Repository: testUARepository(), DashboardCommitSHA: "dddddddddddddddddddddddddddddddddddddddd", Path: "knowledge-graph.json", ExpectedBlobSHA: "ffffffffffffffffffffffffffffffffffffffff", MaxBytes: 1024})
	require.NoError(t, err)
	require.Equal(t, content, file.Content)
	require.Equal(t, "ffffffffffffffffffffffffffffffffffffffff", file.BlobSHA)
}

func TestAGSHTTPRepositoryStoreReadsDashboardFileLargerThanSharedAGSResponseLimit(t *testing.T) {
	content := bytes.Repeat([]byte("x"), (1<<20)+1)
	blob := plumbing.ComputeHash(plumbing.BlobObject, content).String()
	handler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
		writeUATestJSON(w, http.StatusOK, map[string]any{"type": "file", "path": ".ua/knowledge-graph.json", "sha": blob, "size": len(content), "encoding": "base64", "content": base64.StdEncoding.EncodeToString(content)})
	})
	store := AGSHTTPRepositoryStore{Handler: handler}
	file, err := store.ReadUADashboardFile(context.Background(), UADashboardRepositoryFileRequest{Repository: testUARepository(), DashboardCommitSHA: "dddddddddddddddddddddddddddddddddddddddd", Path: "knowledge-graph.json", ExpectedBlobSHA: blob, MaxBytes: int64(len(content))})
	require.NoError(t, err)
	require.Equal(t, content, file.Content)
}

func TestAGSHTTPRepositoryStoreBoundsDashboardContentsResponse(t *testing.T) {
	content := bytes.Repeat([]byte("x"), 1025)
	blob := plumbing.ComputeHash(plumbing.BlobObject, content).String()
	store := AGSHTTPRepositoryStore{Handler: http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
		writeUATestJSON(w, http.StatusOK, map[string]any{"type": "file", "path": ".ua/knowledge-graph.json", "sha": blob, "size": len(content), "encoding": "base64", "content": base64.StdEncoding.EncodeToString(content), "padding": strings.Repeat("x", maxUADashboardAGSResponseOverheadBytes)})
	})}
	_, err := store.ReadUADashboardFile(context.Background(), UADashboardRepositoryFileRequest{Repository: testUARepository(), DashboardCommitSHA: "dddddddddddddddddddddddddddddddddddddddd", Path: "knowledge-graph.json", ExpectedBlobSHA: blob, MaxBytes: 1024})
	require.ErrorContains(t, err, "response exceeds limit")
}

func TestAGSHTTPRepositoryStoreRejectsUnsafeOrMismatchedDashboardFile(t *testing.T) {
	store := AGSHTTPRepositoryStore{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		writeUATestJSON(w, http.StatusOK, map[string]any{"type": "file", "path": ".ua/knowledge-graph.json", "sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "size": 999, "encoding": "base64", "content": base64.StdEncoding.EncodeToString([]byte(`{}`))})
	})}
	for _, request := range []UADashboardRepositoryFileRequest{
		{Repository: testUARepository(), DashboardCommitSHA: "dddddddddddddddddddddddddddddddddddddddd", Path: "../knowledge-graph.json", ExpectedBlobSHA: "ffffffffffffffffffffffffffffffffffffffff", MaxBytes: 10},
		{Repository: testUARepository(), DashboardCommitSHA: "dddddddddddddddddddddddddddddddddddddddd", Path: "knowledge-graph.json", ExpectedBlobSHA: "ffffffffffffffffffffffffffffffffffffffff", MaxBytes: 10},
	} {
		_, err := store.ReadUADashboardFile(context.Background(), request)
		require.Error(t, err)
		require.NotContains(t, err.Error(), `{"type"`)
	}
}

func TestAGSHTTPRepositoryStoreRejectsUnexpectedDashboardFileNames(t *testing.T) {
	store := AGSHTTPRepositoryStore{Handler: http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
		t.Fatal("invalid file names must not call AGS")
	})}
	for _, path := range []string{"diff-overlay.json", "unknown.json", "../knowledge-graph.json"} {
		_, err := store.ReadUADashboardFile(context.Background(), UADashboardRepositoryFileRequest{
			Repository: testUARepository(), DashboardCommitSHA: "dddddddddddddddddddddddddddddddddddddddd",
			Path: path, ExpectedBlobSHA: "ffffffffffffffffffffffffffffffffffffffff", MaxBytes: 10,
		})
		require.Error(t, err, path)
	}
}

func TestAGSHTTPRepositoryStoreRejectsInvalidUADashboardPublishInputs(t *testing.T) {
	store := AGSHTTPRepositoryStore{Handler: http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
		t.Fatal("invalid inputs must not call AGS")
	})}
	for _, request := range []UADashboardRepositoryPublishRequest{
		{Repository: testUARepository(), SourceID: "src-1", Files: map[string][]byte{"domain-graph.json": []byte(`{}`)}},
		{Repository: testUARepository(), SourceID: "src-1", Files: map[string][]byte{"knowledge-graph.json": []byte(`{}`), "unknown.json": []byte(`{}`)}},
		{Repository: func() repos.ResourceRepository {
			value := testUARepository()
			value.RepoRole = repos.RepoRolePrimary
			return value
		}(), SourceID: "src-1", Files: map[string][]byte{"knowledge-graph.json": []byte(`{}`)}},
		{Repository: testUARepository(), SourceID: "../src", Files: map[string][]byte{"knowledge-graph.json": []byte(`{}`)}},
	} {
		_, err := store.PublishUADashboard(context.Background(), request)
		require.Error(t, err)
	}
}

func TestAGSHTTPRepositoryStoreUADashboardErrorsDoNotLeakBodies(t *testing.T) {
	secret := "raw-ags-secret"
	store := AGSHTTPRepositoryStore{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, secret, http.StatusInternalServerError)
	})}
	_, err := store.PublishUADashboard(context.Background(), validTestUAPublishRequest())
	require.Error(t, err)
	require.NotContains(t, err.Error(), secret)
}

func standardUAPublishHandler(t *testing.T, override func(http.ResponseWriter, *http.Request) bool) http.Handler {
	t.Helper()
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if override != nil && override(w, r) {
			return
		}
		switch r.Method + " " + r.URL.Path {
		case "GET /api/v3/repos/org/repo/git/refs/heads/main":
			writeUATestJSON(w, http.StatusOK, map[string]any{"object": map[string]any{"sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}})
		case "GET /api/v3/repos/org/repo/git/commits/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":
			writeUATestJSON(w, http.StatusOK, map[string]any{"sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "tree": map[string]any{"sha": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}})
		case "POST /api/v3/repos/org/repo/git/blobs":
			var body struct {
				Content string `json:"content"`
			}
			require.NoError(t, json.NewDecoder(r.Body).Decode(&body))
			content, err := base64.StdEncoding.DecodeString(body.Content)
			require.NoError(t, err)
			writeUATestJSON(w, http.StatusCreated, map[string]any{"sha": plumbing.ComputeHash(plumbing.BlobObject, content).String()})
		case "POST /api/v3/repos/org/repo/git/trees":
			writeUATestJSON(w, http.StatusCreated, map[string]any{"sha": "cccccccccccccccccccccccccccccccccccccccc"})
		case "GET /api/v3/repos/org/repo/git/trees/cccccccccccccccccccccccccccccccccccccccc":
			writeUATestJSON(w, http.StatusOK, map[string]any{"sha": "cccccccccccccccccccccccccccccccccccccccc", "tree": []map[string]any{{"path": ".ua", "mode": "040000", "type": "tree", "sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}}})
		case "GET /api/v3/repos/org/repo/git/trees/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":
			entries := make([]map[string]any, 0, len(uaDashboardAllowedFiles))
			for path, content := range validTestUAPublishRequest().Files {
				entries = append(entries, map[string]any{"path": path, "mode": "100644", "type": "blob", "sha": plumbing.ComputeHash(plumbing.BlobObject, content).String()})
			}
			writeUATestJSON(w, http.StatusOK, map[string]any{"sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "tree": entries})
		case "POST /api/v3/repos/org/repo/git/commits":
			writeUATestJSON(w, http.StatusCreated, map[string]any{"sha": "dddddddddddddddddddddddddddddddddddddddd"})
		case "GET /api/v3/repos/org/repo/git/commits/dddddddddddddddddddddddddddddddddddddddd":
			writeUATestJSON(w, http.StatusOK, map[string]any{"sha": "dddddddddddddddddddddddddddddddddddddddd", "tree": map[string]any{"sha": "cccccccccccccccccccccccccccccccccccccccc"}, "parents": []map[string]any{{"sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}}})
		case "POST /api/v3/repos/org/repo/git/refs":
			writeUATestJSON(w, http.StatusCreated, map[string]any{"object": map[string]any{"sha": "dddddddddddddddddddddddddddddddddddddddd"}})
		case "GET /api/v3/repos/org/repo/git/refs/meshx/kb-dashboard/src-1/dddddddddddddddddddddddddddddddddddddddd":
			writeUATestJSON(w, http.StatusOK, map[string]any{"ref": "refs/meshx/kb-dashboard/src-1/dddddddddddddddddddddddddddddddddddddddd", "object": map[string]any{"sha": "dddddddddddddddddddddddddddddddddddddddd"}})
		default:
			http.NotFound(w, r)
		}
	})
}

func testUARepository() repos.ResourceRepository {
	return repos.ResourceRepository{ID: "repo-map", WorkspaceID: "ws-1", ResourceType: repos.ResourceTypeKBSource, ResourceID: "src-1", RepoRole: repos.RepoRoleInsights, RepoOwner: "org", RepoName: "repo", RepoFullName: "org/repo", DefaultRef: "main"}
}

func validTestUAPublishRequest() UADashboardRepositoryPublishRequest {
	return UADashboardRepositoryPublishRequest{Repository: testUARepository(), SourceID: "src-1", Files: map[string][]byte{
		UADashboardKnowledgeGraphFile: []byte(`{}`),
		UADashboardDomainGraphFile:    []byte(`{}`),
		UADashboardMetaFile:           []byte(`{}`),
		UADashboardConfigFile:         []byte(`{}`),
		UADashboardFingerprintsFile:   []byte(`{}`),
	}}
}

func writeUATestJSON(w http.ResponseWriter, status int, value any) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	_ = json.NewEncoder(w).Encode(value)
}
