package spindle

import (
	"slices"
	"testing"

	"github.com/bluesky-social/indigo/atproto/syntax"
	kgit "tangled.org/core/knotserver/git"
	"tangled.org/core/spindle/db"
)

func TestHasSkipCIPushOption(t *testing.T) {
	tests := []struct {
		name        string
		pushOptions []string
		want        bool
	}{
		{
			name:        "skip-ci requests skip",
			pushOptions: []string{"skip-ci"},
			want:        true,
		},
		{
			name:        "ci-skip requests skip",
			pushOptions: []string{"ci-skip"},
			want:        true,
		},
		{
			name:        "unrelated ci options do not skip",
			pushOptions: []string{"verbose-ci", "ci-verbose"},
			want:        false,
		},
		{
			name:        "empty options do not skip",
			pushOptions: []string{},
			want:        false,
		},
		{
			name:        "nil options do not skip",
			pushOptions: nil,
			want:        false,
		},
		{
			name:        "mixed options skip when any skip option appears",
			pushOptions: []string{"verbose-ci", "skip-ci", "ci-verbose"},
			want:        true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := kgit.HasSkipCIPushOption(tt.pushOptions)
			if got != tt.want {
				t.Fatalf("hasSkipCIPushOption(%v) = %v, want %v", tt.pushOptions, got, tt.want)
			}
		})
	}
}

func TestSubscribedDids(t *testing.T) {
	d, e := newTestSpindleDB(t)

	var (
		member   = syntax.DID("did:plc:member")
		owner    = syntax.DID("did:plc:owner")
		collab   = syntax.DID("did:plc:collab")
		repoDid  = syntax.DID("did:plc:repo")
		repo2Did = syntax.DID("did:plc:repo2")
	)

	// the repo owner is also a member, so the union has to dedupe
	for _, did := range []syntax.DID{member, owner} {
		if err := d.AllowMember(t.Context(), did); err != nil {
			t.Fatalf("AllowMember(%s): %v", did, err)
		}
	}

	for _, r := range []syntax.DID{repoDid, repo2Did} {
		if err := d.UpsertRepo(db.Repo{
			Knot:    "knot.test",
			Owner:   owner,
			Rkey:    syntax.RecordKey("rkey-" + r.String()),
			RepoDid: r,
		}); err != nil {
			t.Fatalf("UpsertRepo(%s): %v", r, err)
		}
		if err := e.SetRepoOwner(owner, r); err != nil {
			t.Fatalf("SetRepoOwner(%s): %v", r, err)
		}
	}
	// a collaborator who is not a member - the case the members-only filter dropped
	if err := e.AddRepoCollaborator(collab, repoDid); err != nil {
		t.Fatalf("AddRepoCollaborator: %v", err)
	}

	got, err := subscribedDids(d, e)
	if err != nil {
		t.Fatalf("subscribedDids: %v", err)
	}

	want := []syntax.DID{collab, member, owner} // sorted and deduped
	if !slices.Equal(got, want) {
		t.Errorf("subscribedDids() = %v, want %v", got, want)
	}
}
