package extension

import (
	"context"
	"net/http"
	"strings"
	"testing"

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

	"github.com/tidbcloud/AgentTeam/internal/extension/registry"
)

// duplicateExtensionNameAccess returns two accesses sharing one Extension name
// to prove loadAuthorizedExtensions fails closed instead of silently letting the second
// overwrite the first.
type duplicateExtensionNameAccess struct{}

func (duplicateExtensionNameAccess) ActiveAgentDomains(context.Context, string, string) ([]AgentDomainAccess, error) {
	return []AgentDomainAccess{
		{Domain: "tools", ExtensionName: "tools", Actions: []string{"list-items"}},
		{Domain: "tools", ExtensionName: "tools", Actions: []string{"create-item"}},
	}, nil
}

// newRouterForAccessTest builds an Extension runtime router with a custom
// access source (defaulting to permissive) for fail-closed tests.
func newRouterForAccessTest(t *testing.T, access AuthorizationSource) *gin.Engine {
	t.Helper()
	gin.SetMode(gin.ReleaseMode)
	router := gin.New()
	router.HandleMethodNotAllowed = true
	catalog := stubCatalog{extensions: []registry.RegisteredExtension{extensionWithBinding()}}
	if access == nil {
		access = &permissiveCatalogAccess{catalog: catalog}
	}
	RegisterRoutes(router, Dependencies{
		Auth:    authenticator(),
		Catalog: catalog,
		Access:  access,
	})
	return router
}

func runtimeRootTarget() string {
	target := strings.ReplaceAll(RuntimeBase, ":workspaceId", testWorkspace)
	return strings.ReplaceAll(target, ":agentId", testAgent)
}

// TestRoot_DuplicateRoutingExtensionName_Returns5xx proves a duplicate
// Extension name is fail closed: loadAuthorizedExtensions rejects it instead of silently
// overwriting.
func TestRoot_DuplicateRoutingExtensionName_Returns5xx(t *testing.T) {
	t.Parallel()
	router := newRouterForAccessTest(t, duplicateExtensionNameAccess{})
	rec := do(t, router, http.MethodGet, runtimeRootTarget(), testToken, nil)
	assert.Equal(t, http.StatusInternalServerError, rec.Code)
}
