package agent

import (
	"encoding/json"
	"net/http"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/api/dto"
)

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

	router := expectedTaskTestRouter(&expectedTaskBoardService{})
	canonicalPrefix := "/api/v1/workspaces/:workspaceId/agents/:agentId/runtime/tasks"
	got := make(map[string]bool)
	for _, route := range router.Routes() {
		if len(route.Path) >= len(canonicalPrefix) && route.Path[:len(canonicalPrefix)] == canonicalPrefix {
			got[route.Method+" "+route.Path] = true
		}
	}

	require.Equal(t, map[string]bool{
		http.MethodGet + " " + canonicalPrefix:                                   true,
		http.MethodPost + " " + canonicalPrefix:                                  true,
		http.MethodPost + " " + canonicalPrefix + "/get":                         true,
		http.MethodPost + " " + canonicalPrefix + "/update":                      true,
		http.MethodPost + " " + canonicalPrefix + "/add-checkpoint":              true,
		http.MethodPost + " " + canonicalPrefix + "/delete":                      true,
		http.MethodPost + " " + canonicalPrefix + "/set-claim":                   true,
		http.MethodGet + " " + canonicalPrefix + "/:taskScopeId/review-contexts": true,
		http.MethodPut + " " + canonicalPrefix + "/:taskScopeId/review-context":  true,
	}, got)
}

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

	board := &expectedTaskBoardService{
		deleteResponse: DeleteTaskResponse{
			DeletedTaskNumbers:  []int64{7, 8},
			PromotedTaskNumbers: []int64{9},
		},
	}
	response := agentTaskRequest(t, expectedTaskTestRouter(board), http.MethodPost, "/tasks/delete", map[string]any{
		"channel": "#agentteam", "number": 7, "subtaskMode": "promote",
	})

	require.Equal(t, http.StatusOK, response.Code)
	require.Equal(t, "agt_0000000000test", board.deleteRequest.Context.Subject.PrincipalID)
	require.Equal(t, "#agentteam", board.deleteRequest.Board.Channel)
	require.Equal(t, int64(7), board.deleteRequest.Task.TaskNumber)
	require.Equal(t, DeleteTaskSubtaskModePromote, board.deleteRequest.SubtaskMode)

	var result dto.AgentTaskDeleteResponse
	require.NoError(t, json.Unmarshal(response.Body.Bytes(), &result))
	require.Equal(t, []int64{7, 8}, result.DeletedTaskNumbers)
	require.Equal(t, []int64{9}, result.PromotedTaskNumbers)
}

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

	board := &expectedTaskBoardService{}
	response := agentTaskRequest(t, expectedTaskTestRouter(board), http.MethodPost, "/tasks/delete", map[string]any{
		"channel": "#agentteam", "number": 7, "subtaskMode": "cascade",
	})

	require.Equal(t, http.StatusBadRequest, response.Code)
	require.Zero(t, board.deleteRequest.Task.TaskNumber)
}
