package kb

import (
	"context"
	"io"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/desktop/internal/provisioning/asset"
)

type stubResolver struct{ conn asset.ConnectionInfo }

func (s *stubResolver) ResolveServerForAgent(context.Context, string) (asset.ConnectionInfo, bool) {
	return s.conn, true
}

func TestProviderLookupPostsToKBBatchAccessEndpoint(t *testing.T) {
	var capturedPath, capturedBody, capturedAuth, capturedWorkspace string
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		capturedPath = r.URL.Path
		require.Equal(t, "ws_1", r.Header.Get("X-Workspace-Id"))
		require.Equal(t, r.Header.Get("X-Workspace-Id"), r.Header.Get("X-AgentTeam-Route-Workspace-Id"))
		capturedAuth = r.Header.Get("Authorization")
		capturedWorkspace = r.Header.Get("X-Workspace-Id")
		body, _ := io.ReadAll(r.Body)
		capturedBody = string(body)
		w.Header().Set("Content-Type", "application/json")
		_, _ = w.Write([]byte(`{"agents":{"agt_1":[{"id":"kb_1","name":"Runbooks","description":"Ops notes","sources":[{"id":"src_1","name":"AgentTeam","sourceType":"codebase","repositories":[{"repoRole":"canonical","branch":"main","accessProfile":"read","accessStatus":"current","repository":{"repoId":"repo_1","repoFullName":"agentteam/runbooks"}}]}]}]},"syncToken":"ags_rat_kb","syncTokenExpires":"2099-01-02T03:04:05Z"}`))
	}))
	defer ts.Close()

	provider := New(&stubResolver{conn: asset.ConnectionInfo{ServerURL: ts.URL, UserToken: "tok", WorkspaceID: "ws_1", TemplateLocale: "zh-CN"}})
	access, state, err := provider.Lookup(context.Background(), "agt_1")
	require.NoError(t, err)
	require.Equal(t, LookupBound, state)
	require.Len(t, access, 1)
	require.Equal(t, "/api/v1/workspaces/ws_1/kb/agents/access:batch", capturedPath)
	require.Equal(t, "Bearer tok", capturedAuth)
	require.Equal(t, "ws_1", capturedWorkspace)
	require.JSONEq(t, `{"agentIds":["agt_1"],"templateLocale":"zh-CN"}`, capturedBody)

	got := access[0]
	require.Equal(t, "kb_1", got.KnowledgeBaseID)
	require.Equal(t, "Runbooks", got.KnowledgeBaseName)
	require.Equal(t, "src_1", got.SourceID)
	require.Equal(t, "canonical", got.RepoRole)
	require.Equal(t, "main", got.Branch)
	require.Equal(t, "repo_1", got.RepoID)
	require.Equal(t, ts.URL+"/api/v1/workspaces/ws_1/ags/agentteam/runbooks.git", got.CloneURL)
	req, err := http.NewRequest(http.MethodGet, got.CloneURL+"/info/refs", nil)
	require.NoError(t, err)
	got.Auth.SetAuth(req)
	require.Equal(t, "Bearer ags_rat_kb", req.Header.Get("Authorization"))
}

func TestProviderLookupReturnsUnboundWhenNoValidRepositories(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
		_, _ = w.Write([]byte(`{"agents":{"agt_1":[{"id":"kb_1","sources":[{"id":"src_1","repositories":[{"repoRole":"canonical","branch":"main","repository":{"repoId":"repo_1"}}]}]}]}}`))
	}))
	defer ts.Close()

	provider := New(&stubResolver{conn: asset.ConnectionInfo{ServerURL: ts.URL, UserToken: "tok", WorkspaceID: "ws_1"}})
	access, state, err := provider.Lookup(context.Background(), "agt_1")
	require.NoError(t, err)
	require.Equal(t, LookupUnbound, state)
	require.Empty(t, access)
}
