package server

import (
	"bytes"
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	agsconfig "github.com/pingcap/agent-git-service/config"
	agsserver "github.com/pingcap/agent-git-service/server"
	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/config"
	"github.com/tidbcloud/AgentTeam/internal/service/automation"
)

func TestAutomationSourceValidateRejectsOversizedHumanJSONBody(t *testing.T) {
	srv, err := New(config.ResourceRuntimeConfig{
		HTTPAddress: ":0",
		Auth:        config.ResourceRuntimeAuthConfig{Enabled: true, Header: "Authorization"},
		Database:    config.ResourceDatabaseConfig{DSN: meshxDatabaseDSN(t)},
		AGS:         config.AGSConfig{DatabaseDSN: prepareResolverDB(t), GitRepoDir: t.TempDir()},
		Automation:  config.AutomationConfig{MaxAutomationSourceBytes: 8},
	}, Options{AutomationAuthorizer: automation.AllowAutomationAuthorizer{}, NewAGS: func(agsconfig.Config, ...agsserver.Option) (agsServer, error) {
		return fakeAGS{handler: http.NotFoundHandler()}, nil
	}})
	require.NoError(t, err)
	t.Cleanup(func() { require.NoError(t, srv.Shutdown(context.Background())) })

	body := bytes.NewBufferString(`{"content":` + quoteJSON(strings.Repeat("x", 80*1024)) + `}`)
	rec := performAutomationSourceRequest(t, srv, "Bearer "+jwt(map[string]any{"sub": "source-user"}), "ws-source-api", http.MethodPost, "/api/v1/automations/repositories/pingcap/agentteam/definitions/.agentteam%2Fbuild.yml/validate", body)
	require.Equal(t, http.StatusRequestEntityTooLarge, rec.Code, rec.Body.String())
}

func performAutomationSourceRequest(t *testing.T, srv *Server, auth string, workspaceID string, method string, path string, body *bytes.Buffer) *httptest.ResponseRecorder {
	t.Helper()
	if body == nil {
		body = bytes.NewBuffer(nil)
	}
	req := httptest.NewRequest(method, path, body)
	req.Header.Set("Authorization", auth)
	req.Header.Set("X-Workspace-Id", workspaceID)
	rec := httptest.NewRecorder()
	srv.handler.ServeHTTP(rec, req)
	return rec
}

func quoteJSON(value string) string {
	out, _ := json.Marshal(value)
	return string(out)
}
