package exec

import (
	"context"
	"encoding/json"
	"io"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/stretchr/testify/require"

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

func TestProjectHandlerReturnsTypedResults(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case http.MethodGet:
			_, _ = io.WriteString(w, `{"projects":[{"id":"project-1","rootPath":"/repo","name":"Repo"}]}`)
		case http.MethodPost:
			_, _ = io.WriteString(w, `{"project":{"id":"project-2","rootPath":"/repo2","name":"Repo 2"}}`)
		case http.MethodDelete:
			w.WriteHeader(http.StatusNoContent)
		}
	}))
	t.Cleanup(server.Close)
	authorized := runtimeAuthorization{Server: &apiclient.Client{
		ServerURL: server.URL, RouteWorkspaceID: "ws", AgentID: "ag", AuthToken: "token", HTTPClient: server.Client(),
	}}
	h := projectHandler{}
	list, err := h.list(context.Background(), actionScopedJSON[projectListRequest]{Authorized: authorized})
	require.NoError(t, err)
	require.Equal(t, "project-1", list.Data.Projects[0].ID)
	created, err := h.create(context.Background(), actionScopedJSON[projectCreateRequestDTO]{Authorized: authorized, Body: projectCreateRequestDTO{RootPath: "/repo2", Name: "Repo 2"}})
	require.NoError(t, err)
	require.Equal(t, "project-2", created.Data.Project.ID)
	deleted, err := h.delete(context.Background(), actionScopedJSON[projectDeleteRequest]{Authorized: authorized, Body: projectDeleteRequest{ID: "project-2"}})
	require.NoError(t, err)
	require.Equal(t, "project-2", deleted.Data.ID)
}

func TestProjectSchemasUseRootPathAndNonBlankStrings(t *testing.T) {
	create, err := describe(projectCreateSpec)
	require.NoError(t, err)
	require.Contains(t, string(create.InputSchema), `"rootPath"`)
	require.NotContains(t, string(create.InputSchema), `"root_path"`)
	createSchema := mustCompile(t, create.InputSchema)
	require.NoError(t, validateInstance(createSchema, json.RawMessage(`{"rootPath":"/repo","name":"Repo"}`)))
	require.Error(t, validateInstance(createSchema, json.RawMessage(`{"rootPath":"   ","name":"Repo"}`)))
	require.Error(t, validateInstance(createSchema, json.RawMessage(`{"rootPath":"/repo","name":"   "}`)))

	deleteDescriptor, err := describe(projectDeleteSpec)
	require.NoError(t, err)
	deleteSchema := mustCompile(t, deleteDescriptor.InputSchema)
	require.Error(t, validateInstance(deleteSchema, json.RawMessage(`{"id":"   "}`)))
}
