package service_test

import (
	"context"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"testing"

	gitcontract "bit.admedia.com/scm/ad/adpilot-indexing-repo-sync.com/internal/contracts/git"
)

func expectedCommitEventID(snapshotID, commitSHA string) string {
	sum := sha256.Sum256([]byte(commitSHA))
	return fmt.Sprintf("evt_%s_commit_%s", snapshotID, hex.EncodeToString(sum[:4]))
}

func TestCommitEventIDDeterministic(t *testing.T) {
	snapshotID := "snap_test12345678"
	commitSHA := "aaa111"

	got := expectedCommitEventID(snapshotID, commitSHA)
	want := expectedCommitEventID(snapshotID, commitSHA)
	if got != want {
		t.Fatalf("event id not stable: got %q want %q", got, want)
	}
	if got == expectedCommitEventID(snapshotID, "bbb222") {
		t.Fatal("expected different event id for different commit")
	}
}

func TestPublishOrderIncludesCommits(t *testing.T) {
	git := &mockGitProvider{result: sampleSyncResult()}
	pub := &mockEventPublisher{failOnFileIndex: -1, failOnCommitIndex: -1}
	svc := newTestService(git, pub)

	if err := svc.SyncRepository(context.Background(), "ad/example-repo", "main"); err != nil {
		t.Fatalf("SyncRepository: %v", err)
	}

	want := []string{"snapshot", "file", "file", "commit", "commit"}
	pub.mu.Lock()
	got := append([]string(nil), pub.order...)
	pub.mu.Unlock()
	if len(got) != len(want) {
		t.Fatalf("order len: got %v, want %v", got, want)
	}
	for i := range want {
		if got[i] != want[i] {
			t.Fatalf("order[%d]: got %q, want %q", i, got[i], want[i])
		}
	}
}

func TestCommitEventIDMatchesFixture(t *testing.T) {
	result := sampleSyncResult()
	snapshotID := result.Snapshot.SnapshotID
	for _, commit := range result.CommitChanges {
		id := expectedCommitEventID(snapshotID, commit.CommitSHA)
		if id == "" {
			t.Fatal("expected non-empty commit event id")
		}
	}
	_ = gitcontract.CommitChange{}
}
