package db

import "testing"

// TestGetDefaultSignatureFallsBackToMailboxWideDefault confirms an alias with no
// override of its own still gets the mailbox's regular default-for-new/default-for-
// reply signature, rather than "no signature" — the fallback chain
// GetDefaultSignature relies on for every alias that hasn't been given its own
// override.
func TestGetDefaultSignatureFallsBackToMailboxWideDefault(t *testing.T) {
	d := openTestDB(t)
	const mailboxID = int64(1)

	id, err := d.CreateSignature(mailboxID, "Work", "<p>Work sig</p>")
	if err != nil {
		t.Fatal(err)
	}
	if err := d.SetDefaultSignature(mailboxID, id, false); err != nil {
		t.Fatal(err)
	}

	sig, err := d.GetDefaultSignature(mailboxID, false, "alias@example.com")
	if err != nil || sig == nil || sig.ID != id {
		t.Fatalf("expected fallback to the mailbox-wide default, got %+v (err=%v)", sig, err)
	}
}

// TestGetDefaultSignatureAliasOverrideWins confirms an alias with its own override
// gets that signature instead of the mailbox-wide default, even when both exist.
func TestGetDefaultSignatureAliasOverrideWins(t *testing.T) {
	d := openTestDB(t)
	const mailboxID = int64(1)

	generalID, err := d.CreateSignature(mailboxID, "General", "<p>General</p>")
	if err != nil {
		t.Fatal(err)
	}
	if err := d.SetDefaultSignature(mailboxID, generalID, false); err != nil {
		t.Fatal(err)
	}
	supportID, err := d.CreateSignature(mailboxID, "Support", "<p>Support</p>")
	if err != nil {
		t.Fatal(err)
	}
	if err := d.SetSignatureAliasDefault(mailboxID, supportID, "support@example.com", false); err != nil {
		t.Fatal(err)
	}

	sig, err := d.GetDefaultSignature(mailboxID, false, "support@example.com")
	if err != nil || sig == nil || sig.ID != supportID {
		t.Fatalf("expected the alias override (Support), got %+v (err=%v)", sig, err)
	}

	// A different, unrelated address still gets the mailbox-wide default.
	sig, err = d.GetDefaultSignature(mailboxID, false, "someone-else@example.com")
	if err != nil || sig == nil || sig.ID != generalID {
		t.Fatalf("expected the mailbox-wide default (General) for an address with no override, got %+v (err=%v)", sig, err)
	}
}

// TestSetSignatureAliasDefaultUpsertsRepointing confirms re-setting the same
// (mailbox, alias, new-or-reply) scope to a different signature repoints it instead
// of erroring on the UNIQUE constraint.
func TestSetSignatureAliasDefaultUpsertsRepointing(t *testing.T) {
	d := openTestDB(t)
	const mailboxID = int64(1)

	firstID, _ := d.CreateSignature(mailboxID, "First", "<p>First</p>")
	secondID, _ := d.CreateSignature(mailboxID, "Second", "<p>Second</p>")

	if err := d.SetSignatureAliasDefault(mailboxID, firstID, "alias@example.com", false); err != nil {
		t.Fatal(err)
	}
	if err := d.SetSignatureAliasDefault(mailboxID, secondID, "alias@example.com", false); err != nil {
		t.Fatalf("expected re-setting the same scope to upsert cleanly, got: %v", err)
	}

	sig, err := d.GetDefaultSignature(mailboxID, false, "alias@example.com")
	if err != nil || sig == nil || sig.ID != secondID {
		t.Fatalf("expected the scope repointed to Second, got %+v (err=%v)", sig, err)
	}
}

// TestClearSignatureAliasDefaultFallsBack confirms clearing an alias override falls
// back to the mailbox-wide default again, rather than leaving "no signature".
func TestClearSignatureAliasDefaultFallsBack(t *testing.T) {
	d := openTestDB(t)
	const mailboxID = int64(1)

	generalID, _ := d.CreateSignature(mailboxID, "General", "<p>General</p>")
	d.SetDefaultSignature(mailboxID, generalID, false)
	supportID, _ := d.CreateSignature(mailboxID, "Support", "<p>Support</p>")
	d.SetSignatureAliasDefault(mailboxID, supportID, "support@example.com", false)

	if err := d.ClearSignatureAliasDefault(mailboxID, "support@example.com", false); err != nil {
		t.Fatal(err)
	}
	sig, err := d.GetDefaultSignature(mailboxID, false, "support@example.com")
	if err != nil || sig == nil || sig.ID != generalID {
		t.Fatalf("expected fallback to General after clearing the override, got %+v (err=%v)", sig, err)
	}
}

// TestDeleteSignatureCleansUpAliasDefaults confirms deleting a signature that's an
// alias's default doesn't leave a dangling row pointing at a nonexistent signature.
func TestDeleteSignatureCleansUpAliasDefaults(t *testing.T) {
	d := openTestDB(t)
	const mailboxID = int64(1)

	supportID, _ := d.CreateSignature(mailboxID, "Support", "<p>Support</p>")
	d.SetSignatureAliasDefault(mailboxID, supportID, "support@example.com", false)

	if err := d.DeleteSignature(mailboxID, supportID); err != nil {
		t.Fatal(err)
	}
	defaults, err := d.ListSignatureAliasDefaults(mailboxID)
	if err != nil {
		t.Fatal(err)
	}
	if len(defaults) != 0 {
		t.Fatalf("expected the alias default row cleaned up alongside the deleted signature, got %+v", defaults)
	}
}
