package mcp_test

import (
	"context"
	"testing"

	"github.com/google/uuid"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"github.com/yan1h/agent-coding-workflow/internal/infra/errs"
	"github.com/yan1h/agent-coding-workflow/internal/mcp"
)

func TestCheckToolFromCtx_Allowed(t *testing.T) {
	t.Parallel()
	ctx := context.WithValue(context.Background(), mcp.AuthContextKey,
		&mcp.AuthSession{Scope: mcp.Scope{Tools: []string{"list_issues"}}})
	require.NoError(t, mcp.CheckToolFromCtx(ctx, "list_issues"))
}

func TestCheckToolFromCtx_Denied(t *testing.T) {
	t.Parallel()
	ctx := context.WithValue(context.Background(), mcp.AuthContextKey,
		&mcp.AuthSession{Scope: mcp.Scope{Tools: []string{"list_issues"}}})

	err := mcp.CheckToolFromCtx(ctx, "create_issue")
	ae, ok := errs.As(err)
	require.True(t, ok)
	assert.Equal(t, errs.CodeMcpTokenScopeViolation, ae.Code)
}

func TestCheckToolFromCtx_NilTools_AllowsAll(t *testing.T) {
	t.Parallel()
	ctx := context.WithValue(context.Background(), mcp.AuthContextKey,
		&mcp.AuthSession{Scope: mcp.Scope{Tools: nil}})
	require.NoError(t, mcp.CheckToolFromCtx(ctx, "anything"))
}

func TestCheckToolFromCtx_NoSession(t *testing.T) {
	t.Parallel()
	err := mcp.CheckToolFromCtx(context.Background(), "x")
	ae, ok := errs.As(err)
	require.True(t, ok)
	assert.Equal(t, errs.CodeInternal, ae.Code)
}

func TestCheckProjectFromCtx_Allowed(t *testing.T) {
	t.Parallel()
	pid := uuid.New()
	ctx := context.WithValue(context.Background(), mcp.AuthContextKey,
		&mcp.AuthSession{Scope: mcp.Scope{ProjectIDs: []uuid.UUID{pid}}})
	require.NoError(t, mcp.CheckProjectFromCtx(ctx, pid))
}

func TestCheckProjectFromCtx_Denied(t *testing.T) {
	t.Parallel()
	a, b := uuid.New(), uuid.New()
	ctx := context.WithValue(context.Background(), mcp.AuthContextKey,
		&mcp.AuthSession{Scope: mcp.Scope{ProjectIDs: []uuid.UUID{a}}})

	err := mcp.CheckProjectFromCtx(ctx, b)
	ae, ok := errs.As(err)
	require.True(t, ok)
	assert.Equal(t, errs.CodeMcpTokenScopeViolation, ae.Code)
}

func TestCheckProjectFromCtx_NilProjectIDs_AllowsAll(t *testing.T) {
	t.Parallel()
	ctx := context.WithValue(context.Background(), mcp.AuthContextKey,
		&mcp.AuthSession{Scope: mcp.Scope{ProjectIDs: nil}})
	require.NoError(t, mcp.CheckProjectFromCtx(ctx, uuid.New()))
}
