package app

import (
	"context"
	"errors"
	"testing"
	"time"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/extension/connection"
	"github.com/tidbcloud/AgentTeam/internal/store/app/registry"
	"github.com/tidbcloud/AgentTeam/internal/store/model"
	"github.com/tidbcloud/AgentTeam/internal/store/serviceactor"
)

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

	ctx := context.Background()
	pool := startAppRollbackDB(t, ctx)
	store := New(pool, Options{
		AppCredentialStorageKey: testAppCredentialStorageKey(),
	})
	now := time.Now().UTC()
	admin := seedAppAdminFixture(t, pool, "jenkins_connection", now)
	target := ExtensionProviderTarget{
		AppID:   registry.JenkinsAppID,
		AppSlug: registry.JenkinsAppSlug,
		Label:   "Jenkins",
	}

	installation, err := store.InstallAppForWorkspaceAdmin(
		ctx,
		admin.UserID,
		admin.WorkspaceID,
		InstallAppParams{AppID: registry.JenkinsAppID},
	)
	require.NoError(t, err)
	selections, err := serviceactor.New(pool).ListInstallationExtensions(
		ctx,
		admin.WorkspaceID,
		installation.ID,
	)
	require.NoError(t, err)
	require.Len(t, selections, 1)
	require.Equal(t, "jenkins", selections[0].ExtensionName)
	require.Equal(t,
		model.JenkinsBuiltinExtensionDefinitionDigest,
		selections[0].DefinitionDigest,
	)

	credentials := map[string]string{
		"baseUrl":  "https://jenkins.example/jenkins",
		"username": "builder",
		"apiToken": "jenkins-secret",
	}
	view, err := store.UpsertExtensionProviderConnectionForUser(
		ctx,
		admin.UserID,
		admin.WorkspaceID,
		installation.ID,
		target,
		credentials,
		nil,
		nil,
	)
	require.NoError(t, err)
	require.True(t, view.Active)
	require.True(t, view.CredentialSet)

	var storedCredentials []byte
	require.NoError(t, pool.QueryRow(ctx, `
SELECT credentials
FROM service_connections
WHERE service_installation_id = $1
  AND external_subject_ref = 'default'
  AND status = 'active'
`, installation.ID).Scan(&storedCredentials))
	require.NotContains(t, string(storedCredentials), "jenkins-secret")
	require.NotContains(t, string(storedCredentials), "builder")
	require.Contains(t, string(storedCredentials), CredentialStorageScheme)

	resolved, _, err := store.ResolveExtensionProviderRuntimeConnection(
		ctx,
		admin.WorkspaceID,
		installation.ID,
		ExtensionProviderTarget{},
		connection.Contract{},
	)
	require.NoError(t, err)
	require.Equal(t, credentials, resolved)

	peer := seedWorkspaceMemberFixture(
		t,
		pool,
		admin.WorkspaceID,
		"jenkins_connection_peer",
		now,
	)
	_, err = store.GetExtensionProviderConnectionForUser(
		ctx,
		peer.UserID,
		admin.WorkspaceID,
		installation.ID,
		target,
	)
	require.Error(t, err)
	require.True(t, errors.Is(err, ErrForbidden))

	require.NoError(t, store.DeleteExtensionProviderConnectionForUser(
		ctx,
		admin.UserID,
		admin.WorkspaceID,
		installation.ID,
		target,
	))
	_, _, err = store.ResolveExtensionProviderRuntimeConnection(
		ctx,
		admin.WorkspaceID,
		installation.ID,
		ExtensionProviderTarget{},
		connection.Contract{},
	)
	require.Error(t, err)
}
