package webhooks

import (
	"context"
	"database/sql"
	"errors"
	"reflect"
	"testing"

	"github.com/tidbcloud/AgentTeam/internal/coredb"
	"github.com/tidbcloud/AgentTeam/internal/store/app/runtime"
)

func TestLoadAppDefinitionTrimsAndPreservesNotFoundSemantics(t *testing.T) {
	t.Parallel()

	queryer := &scriptedWebhookQueryer{row: scriptedWebhookRow{values: []any{" app-1 ", " github ", " third_party "}}}
	app, err := LoadAppDefinition(context.Background(), queryer, " github ")
	if err != nil {
		t.Fatalf("LoadAppDefinition returned error: %v", err)
	}
	if app != (AppDefinition{AppID: "app-1", AppSlug: "github", AppKind: "third_party"}) {
		t.Fatalf("app = %#v", app)
	}
	if got, want := queryer.args, []any{"github"}; !reflect.DeepEqual(got, want) {
		t.Fatalf("query args = %#v, want %#v", got, want)
	}

	_, err = LoadAppDefinition(context.Background(), &scriptedWebhookQueryer{row: scriptedWebhookRow{err: sql.ErrNoRows}}, "missing")
	if !errors.Is(err, ErrNotFound) {
		t.Fatalf("err = %v, want ErrNotFound", err)
	}
}

func TestProviderWatchResolversMatchGitHubAndGiteaRules(t *testing.T) {
	t.Parallel()

	githubConnections := []runtime.ConnectionView{
		{ExternalSubjectRef: "123", DisplayLabel: "pingcap"},
		{ExternalSubjectRef: "456", DisplayLabel: "other"},
	}
	ref, status := ResolveGitHubServiceEventConnectionFromConnections(githubConnections, "PingCAP/agentteam", "")
	if ref != "123" || status != ServiceEventConnectionReady {
		t.Fatalf("github ref/status = %q/%s", ref, status)
	}
	ref, status = ResolveGitHubServiceEventConnectionFromConnections(githubConnections, "PingCAP/agentteam", "456")
	if ref != "" || status != ServiceEventConnectionResourceNotAccessible {
		t.Fatalf("github expected-mismatch ref/status = %q/%s", ref, status)
	}

	giteaConnections := []runtime.ConnectionView{
		{ExternalSubjectRef: "pingcap"},
		{ExternalSubjectRef: "pingcap/agentteam"},
	}
	ref, status = ResolveGiteaServiceEventConnectionFromConnections(giteaConnections, "PingCAP/AgentTeam", "")
	if ref != "pingcap/agentteam" || status != ServiceEventConnectionReady {
		t.Fatalf("gitea repo ref/status = %q/%s", ref, status)
	}
	ref, status = ResolveGiteaServiceEventConnectionFromConnections(giteaConnections, "PingCAP/AgentTeam", "pingcap")
	if ref != "pingcap" || status != ServiceEventConnectionReady {
		t.Fatalf("gitea owner ref/status = %q/%s", ref, status)
	}
}

type scriptedWebhookQueryer struct {
	row  scriptedWebhookRow
	args []any
}

func (queryer *scriptedWebhookQueryer) QueryRow(_ context.Context, _ string, args ...any) coredb.Row {
	queryer.args = append([]any(nil), args...)
	return queryer.row
}

type scriptedWebhookRow struct {
	values []any
	err    error
}

func (row scriptedWebhookRow) Scan(dest ...any) error {
	if row.err != nil {
		return row.err
	}
	for idx, value := range row.values {
		*(dest[idx].(*string)) = value.(string)
	}
	return nil
}
