package extensione2e

import (
	"net/http/httptest"
	"testing"

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/desktop/internal/api/exec"
	"github.com/tidbcloud/AgentTeam/desktop/internal/token"
	"github.com/tidbcloud/AgentTeam/desktop/internal/wire/apiclient"
)

type desktopExecRuntime struct {
	authorizations *exec.RuntimeAuthorizationStore
	credential     exec.RuntimeCredentialLease
	view           *exec.RuntimeCatalogView
	baseURL        string
	client         exec.LocalClient
	close          func()
}

func newDesktopExecRuntime(
	t *testing.T,
	server *apiclient.Client,
	snapshot exec.ExtensionSnapshot,
	processGeneration string,
) desktopExecRuntime {
	t.Helper()
	builtin, err := exec.DefaultCatalog()
	require.NoError(t, err)
	catalog, err := exec.NewRuntimeCatalog(builtin, snapshot)
	require.NoError(t, err)
	manager, err := token.NewKeyManager(t.TempDir() + "/config.yaml")
	require.NoError(t, err)
	authorizations := exec.NewRuntimeAuthorizationStore(manager)
	credential, err := authorizations.Create(exec.RuntimeAuthorizationConfig{
		ServerID:          "server-1",
		AgentID:           e2eAgent,
		SessionID:         "session-" + processGeneration,
		RunID:             "run-" + processGeneration,
		WorkDir:           t.TempDir(),
		ProcessGeneration: processGeneration,
		RuntimeCatalog:    catalog,
		Server:            server,
	})
	require.NoError(t, err)
	router := gin.New()
	exec.RegisterRoutes(
		router.Group("/api/internal/exec"),
		exec.RouteDependencies{Authorizations: authorizations},
	)
	localServer := httptest.NewServer(router)
	view, err := catalog.View()
	require.NoError(t, err)
	return desktopExecRuntime{
		authorizations: authorizations,
		credential:     credential,
		view:           view,
		baseURL: localServer.URL +
			"/api/internal/exec/servers/server-1/agents/" + e2eAgent,
		client: exec.LocalClient{HTTPClient: localServer.Client()},
		close:  localServer.Close,
	}
}

func (runtime desktopExecRuntime) revoke(t *testing.T) {
	t.Helper()
	<-runtime.authorizations.Revoke(runtime.credential.AuthorizationID)
}
