package memory

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/service/resource/repos"
	"github.com/tidbcloud/AgentTeam/presets"
)

func TestInitializeMemoryRepositoryUsesConfiguredAGSAuthHeaderForGoGitPush(t *testing.T) {
	const internalAuth = "Bearer internal.jwt."
	requests := make(chan http.Header, 4)
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		requests <- r.Header.Clone()
		http.Error(w, `{"message":"Bad credentials"}`, http.StatusUnauthorized)
	}))
	t.Cleanup(server.Close)

	store := AGSHTTPRepositoryStore{
		BaseURL:             server.URL,
		AuthHeader:          "X-AgentTeam-JWT",
		AuthorizationHeader: internalAuth,
	}

	err := store.InitializeMemoryRepository(context.Background(), MemoryRepositoryInitializeRequest{
		Repository: repos.RepositoryIdentity{Owner: "owner", Name: "repo", FullName: "owner/repo", DefaultBranch: "main"},
		Locale:     "en",
	})
	require.Error(t, err)

	var captured http.Header
	select {
	case captured = <-requests:
	default:
		require.Fail(t, "expected go-git push to reach test server")
	}
	require.Equal(t, internalAuth, captured.Get("X-AgentTeam-JWT"))
	require.Empty(t, captured.Get("Authorization"))
}

func TestInitializeMemoryRepositoryUsesAuthorizationWhenConfiguredAsAGSAuthHeader(t *testing.T) {
	const internalAuth = "Bearer internal.jwt."
	requests := make(chan http.Header, 4)
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		requests <- r.Header.Clone()
		http.Error(w, `{"message":"Bad credentials"}`, http.StatusUnauthorized)
	}))
	t.Cleanup(server.Close)

	store := AGSHTTPRepositoryStore{
		BaseURL:             server.URL,
		AuthHeader:          "Authorization",
		AuthorizationHeader: internalAuth,
	}

	err := store.InitializeMemoryRepository(context.Background(), MemoryRepositoryInitializeRequest{
		Repository: repos.RepositoryIdentity{Owner: "owner", Name: "repo", FullName: "owner/repo", DefaultBranch: "main"},
		Locale:     "en",
	})
	require.Error(t, err)

	var captured http.Header
	select {
	case captured = <-requests:
	default:
		require.Fail(t, "expected go-git push to reach test server")
	}
	require.Equal(t, internalAuth, captured.Get("Authorization"))
}

func TestEnsureMemoryRepositoryLabelsCreatesLocalizedMissingLabels(t *testing.T) {
	var created []map[string]string
	var sawAuth bool
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		sawAuth = true
		require.Equal(t, "Bearer internal.jwt.", r.Header.Get("X-AgentTeam-JWT"))
		require.Empty(t, r.Header.Get("Authorization"))
		switch {
		case r.Method == http.MethodGet && r.URL.Path == "/api/v3/repos/ws/runbooks.mem/labels":
			require.Equal(t, "100", r.URL.Query().Get("per_page"))
			require.NoError(t, json.NewEncoder(w).Encode([]map[string]string{{"name": "知识"}}))
		case r.Method == http.MethodPost && r.URL.Path == "/api/v3/repos/ws/runbooks.mem/labels":
			var body map[string]string
			require.NoError(t, json.NewDecoder(r.Body).Decode(&body))
			created = append(created, body)
			w.WriteHeader(http.StatusCreated)
			require.NoError(t, json.NewEncoder(w).Encode(body))
		default:
			require.Failf(t, "unexpected request", "%s %s", r.Method, r.URL.String())
		}
	})
	store := AGSHTTPRepositoryStore{
		Handler:             handler,
		AuthHeader:          "X-AgentTeam-JWT",
		AuthorizationHeader: "Bearer internal.jwt.",
	}

	err := store.ensureMemoryRepositoryLabels(context.Background(), "ws", "runbooks.mem", presets.MemoryLabels("zh-CN"))

	require.NoError(t, err)
	require.True(t, sawAuth)
	require.Len(t, created, 9)
	require.Equal(t, "洞察", created[0]["name"])
	require.Equal(t, "bf3989", created[0]["color"])
	require.NotEmpty(t, created[0]["description"])
	require.Equal(t, "模板", created[len(created)-1]["name"])
}
