package canonical

import (
	"testing"
	"time"
)

func TestComparableHashExcludesProviderIdentityAndProvenance(t *testing.T) {
	now := time.Now().UTC()
	a := NewRecord(TypeIssue, "github:1", "issue:one", map[string]any{"title": "one", "body": "body"})
	a.OriginalActor, a.OriginalTime = "alice", &now
	b := a
	b.Identity, b.OriginalActor, b.SourceURL = "ags:9", "sync-app", "https://example.test"
	ha, err := a.ComparableHash()
	if err != nil {
		t.Fatal(err)
	}
	hb, err := b.ComparableHash()
	if err != nil {
		t.Fatal(err)
	}
	if ha != hb {
		t.Fatalf("provider metadata changed comparable hash: %s != %s", ha, hb)
	}
}

func TestComparableHashExcludesUnmappedAssigneeIdentity(t *testing.T) {
	left := NewRecord(TypeIssue, "1", "issue:1", map[string]any{"title": "same", "assignees": []string{"alice"}})
	right := NewRecord(TypeIssue, "2", "issue:2", map[string]any{"title": "same", "assignees": []string{"somebody-else"}})
	leftHash, err := left.ComparableHash()
	if err != nil {
		t.Fatal(err)
	}
	rightHash, err := right.ComparableHash()
	if err != nil {
		t.Fatal(err)
	}
	if leftHash != rightHash {
		t.Fatalf("unmapped provider account changed comparable hash")
	}
}

func TestPullRequestComparableHashExcludesProviderDerivedSHAs(t *testing.T) {
	left := NewRecord(TypePullRequest, "1", "pull:1", map[string]any{"title": "same", "head_sha": "aaa", "base_sha": "bbb"})
	right := NewRecord(TypePullRequest, "2", "pull:2", map[string]any{"title": "same", "head_sha": "ccc", "base_sha": "ddd"})
	leftHash, _ := left.ComparableHash()
	rightHash, _ := right.ComparableHash()
	if leftHash != rightHash {
		t.Fatalf("provider-derived PR SHA changed comparable hash")
	}
}

func TestPullRequestReviewComparableHashExcludesProviderAssignedCommit(t *testing.T) {
	left := NewRecord(TypePullRequestReview, "1", "review:1", map[string]any{"body": "LGTM", "commit_id": ""})
	right := NewRecord(TypePullRequestReview, "2", "review:2", map[string]any{"body": "LGTM", "commit_id": "github-default-head"})
	leftHash, err := left.ComparableHash()
	if err != nil {
		t.Fatal(err)
	}
	rightHash, err := right.ComparableHash()
	if err != nil {
		t.Fatal(err)
	}
	if leftHash != rightHash {
		t.Fatalf("review hashes differ: %s != %s", leftHash, rightHash)
	}
}

func TestManagedBodyRoundTrip(t *testing.T) {
	body := RenderManagedBody("hello", "https://ags.test/o/r/issues/1", "alice", nil, 42)
	parsed := StripManagedBody(body)
	if parsed.Body != "hello" || parsed.ObjectLinkID != 42 {
		t.Fatalf("parsed = %#v", parsed)
	}
}

func TestTargetStateFromInventoryIncludesNumberAndURL(t *testing.T) {
	record := NewRecord(TypeIssue, "node", "issue:node", map[string]any{"_number": 42, "title": "x"})
	record.SourceURL = "https://example.test/issues/42"
	object, err := record.Inventory("rev", "native")
	if err != nil {
		t.Fatal(err)
	}
	state := TargetStateFromInventory(object, true)
	if state.Number != 42 || state.URL != record.SourceURL || !state.Managed {
		t.Fatalf("state=%#v", state)
	}
}
