package exec

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

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

func TestApiclientWorkspaceAPI(t *testing.T) {
	var method, path, rawQuery, auth string
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		method, path, rawQuery, auth = r.Method, r.URL.EscapedPath(), r.URL.RawQuery, r.Header.Get("Authorization")
		_, _ = io.WriteString(w, `{"channels":[{"name":"general","displayName":"General"}],"hasMore":true,"nextCursor":"page-2"}`)
	}))
	defer srv.Close()
	api := workspaceRemote{client: &apiclient.Client{ServerURL: srv.URL, AgentID: "ag", AuthToken: "tok", RouteWorkspaceID: "ws", HTTPClient: srv.Client()}}

	t.Run("list GET /workspace with Bearer", func(t *testing.T) {
		method, path, auth = "", "", ""
		result, err := api.list(context.Background(), "summary", "", 20, "")
		if err != nil {
			t.Fatal(err)
		}
		if method != http.MethodGet || path != "/api/v1/workspaces/ws/agents/ag/runtime/workspace" || rawQuery != "kind=summary&limit=20" {
			t.Errorf("request: %s %s?%s", method, path, rawQuery)
		}
		if auth != "Bearer tok" {
			t.Errorf("bearer: %q", auth)
		}
		if len(result.Channels) != 1 || result.Channels[0].Name != "general" {
			t.Errorf("result: %+v", result)
		}
		if !result.HasMore || result.NextCursor != "page-2" {
			t.Errorf("pagination mapping: %+v", result)
		}
	})
	t.Run("list cursor and query in query string", func(t *testing.T) {
		var gotPath, gotQuery string
		srv2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			gotPath = r.URL.EscapedPath()
			gotQuery = r.URL.RawQuery
			_, _ = io.WriteString(w, `{}`)
		}))
		defer srv2.Close()
		api2 := workspaceRemote{client: &apiclient.Client{ServerURL: srv2.URL, AgentID: "ag", AuthToken: "tok", RouteWorkspaceID: "ws", HTTPClient: srv2.Client()}}
		_, err := api2.list(context.Background(), "channels", "dev", 50, "c1")
		if err != nil {
			t.Fatal(err)
		}
		if gotPath != "/api/v1/workspaces/ws/agents/ag/runtime/workspace" || gotQuery != "cursor=c1&kind=channels&limit=50&query=dev" {
			t.Errorf("URL: %s?%s", gotPath, gotQuery)
		}
	})
	t.Run("runtime gates stable error", func(t *testing.T) {
		for _, client := range []*apiclient.Client{
			nil,
			{RouteWorkspaceID: "ws", AgentID: "ag", AuthToken: "tok"},
			{RouteWorkspaceID: "ws", HTTPClient: srv.Client()},
			{AgentID: "ag", AuthToken: "tok", HTTPClient: srv.Client()},
		} {
			empty := workspaceRemote{client: client}
			if _, err := empty.list(context.Background(), "summary", "", 20, ""); err == nil {
				t.Fatalf("client %+v passed gate", client)
			}
		}
	})
	t.Run("404 maps to not_found through handler", func(t *testing.T) {
		notFound := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.WriteHeader(http.StatusNotFound)
		}))
		defer notFound.Close()
		bad := workspaceRemote{client: &apiclient.Client{ServerURL: notFound.URL, AgentID: "ag", AuthToken: "tok", RouteWorkspaceID: "ws", HTTPClient: notFound.Client()}}
		_, err := bad.list(context.Background(), "summary", "", 20, "")
		errIsCode(t, classifyAPIError(err, "list workspace failed"), CodeNotFound)
	})
}
