package agent

import (
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/desktop/internal/agent/drivercontract"
)

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

	workDir := t.TempDir()
	cfg := testLaunchConfig(drivercontract.LaunchConfig{WorkDir: workDir, ContractCarrierFile: "AGENTS.md"}, testLaunchSurfaces{RuntimeCarrier: "native contract text"})

	require.NoError(t, materializeContractCarrier(cfg))

	data, err := os.ReadFile(filepath.Join(workDir, "AGENTS.md"))
	require.NoError(t, err)
	require.Contains(t, string(data), agentteamManagedContractStart)
	require.Contains(t, string(data), "native contract text")
	require.Contains(t, string(data), agentteamManagedContractEnd)
}

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

	err := materializeContractCarrier(testLaunchConfig(drivercontract.LaunchConfig{WorkDir: t.TempDir(), ContractCarrierFile: "nested/AGENTS.md"}, testLaunchSurfaces{RuntimeCarrier: "native contract text"}))
	require.Error(t, err)
}

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

	workDir := t.TempDir()
	require.NoError(t, materializeContractCarrier(testLaunchConfig(drivercontract.LaunchConfig{WorkDir: workDir, ContractCarrierFile: "AGENTS.md"}, testLaunchSurfaces{RuntimeCarrier: "   \n\t"})))

	_, err := os.Stat(filepath.Join(workDir, "AGENTS.md"))
	require.ErrorIs(t, err, os.ErrNotExist)
}

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

	workDir := t.TempDir()
	path := filepath.Join(workDir, "AGENTS.md")
	require.NoError(t, os.WriteFile(path, []byte("user content"), 0o644))

	require.NoError(t, materializeContractCarrier(testLaunchConfig(drivercontract.LaunchConfig{WorkDir: workDir, ContractCarrierFile: "AGENTS.md"}, testLaunchSurfaces{RuntimeCarrier: "agentteam contract text"})))

	data, err := os.ReadFile(path)
	require.NoError(t, err)
	require.Contains(t, string(data), "user content")
	require.Contains(t, string(data), "agentteam contract text")
	require.Contains(t, string(data), agentteamManagedContractStart)
}

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

	workDir := t.TempDir()
	path := filepath.Join(workDir, "AGENTS.md")
	require.NoError(t, os.WriteFile(path, []byte("user content\n\n"+agentteamManagedContractStart+"\nold contract\n"+agentteamManagedContractEnd+"\n"), 0o644))

	require.NoError(t, materializeContractCarrier(testLaunchConfig(drivercontract.LaunchConfig{WorkDir: workDir, ContractCarrierFile: "AGENTS.md"}, testLaunchSurfaces{RuntimeCarrier: "new contract"})))

	data, err := os.ReadFile(path)
	require.NoError(t, err)
	require.Contains(t, string(data), "user content")
	require.NotContains(t, string(data), "old contract")
	require.Contains(t, string(data), "new contract")
	require.Equal(t, 1, strings.Count(string(data), agentteamManagedContractStart))
}
