package rest_test

import (
	"fmt"
	"net/http"
	"strings"
	"testing"

	"github.com/pingcap/agent-git-service/internal/testharness"
)

func TestListCommitsPaginatesTheCompleteHistory(t *testing.T) {
	h := testharness.New(t)
	ctx := h.Tenant.Context()
	fullName := createGitRepo(t, h, "commit-history-pagination", "main", true)

	for i := 1; i <= 35; i++ {
		message := fmt.Sprintf("history commit %02d", i)
		if _, err := h.Tenant.Git().WriteFile(ctx, fullName, "main", "history.txt", message, []byte(message)); err != nil {
			t.Fatalf("write commit %d: %v", i, err)
		}
	}

	first := h.DoREST(t, http.MethodGet, "/api/v3/repos/"+fullName+"/commits?sha=main&page=1&per_page=30", nil)
	assertStatusCode(t, first, http.StatusOK)
	if got := len(testharness.DecodeJSONArray(t, first)); got != 30 {
		t.Fatalf("first page commit count = %d, want 30", got)
	}
	if link := first.Header().Get("Link"); !strings.Contains(link, "page=2") || !strings.Contains(link, `rel="next"`) || !strings.Contains(link, `rel="last"`) || !strings.Contains(link, "sha=main") {
		t.Fatalf("first-page Link header = %q, want next/last links for page 2 that preserve sha", link)
	}

	second := h.DoREST(t, http.MethodGet, "/api/v3/repos/"+fullName+"/commits?sha=main&page=2&per_page=30", nil)
	assertStatusCode(t, second, http.StatusOK)
	items := testharness.DecodeJSONArray(t, second)
	if got := len(items); got != 6 { // initial commit plus 35 history commits
		t.Fatalf("second page commit count = %d, want 6", got)
	}
	if link := second.Header().Get("Link"); strings.Contains(link, `rel="next"`) || !strings.Contains(link, `rel="prev"`) || !strings.Contains(link, `rel="first"`) {
		t.Fatalf("second-page Link header = %q, want prev/first only", link)
	}
}

func TestListCommitsUsesRequestedRevision(t *testing.T) {
	h := testharness.New(t)
	ctx := h.Tenant.Context()
	fullName := createGitRepo(t, h, "commit-history-ref", "main", true)

	mainSHA, err := h.Tenant.Git().HeadSHA(ctx, fullName, "main")
	if err != nil {
		t.Fatalf("head main: %v", err)
	}
	if err := h.Tenant.Git().UpdateRef(ctx, fullName, "refs/heads/feature/history", mainSHA); err != nil {
		t.Fatalf("create feature branch: %v", err)
	}
	featureSHA, err := h.Tenant.Git().WriteFile(ctx, fullName, "feature/history", "feature.txt", "feature-only commit", []byte("feature"))
	if err != nil {
		t.Fatalf("write feature commit: %v", err)
	}

	w := h.DoREST(t, http.MethodGet, "/api/v3/repos/"+fullName+"/commits?sha=feature%2Fhistory", nil)
	assertStatusCode(t, w, http.StatusOK)
	items := testharness.DecodeJSONArray(t, w)
	if len(items) == 0 {
		t.Fatal("feature history is empty")
	}
	if got := items[0]["sha"]; got != featureSHA {
		t.Fatalf("feature history head = %v, want %q", got, featureSHA)
	}
}
