package agent

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

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

const (
	agentteamManagedContractStart = "<!-- AGENTTEAM_MANAGED_CONTRACT_START -->"
	agentteamManagedContractEnd   = "<!-- AGENTTEAM_MANAGED_CONTRACT_END -->"
)

// materializeContractCarrier writes a runtime-native contract carrier file into
// the agent workdir when the runtime expects prompt instructions from disk.
func materializeContractCarrier(cfg drivercontract.LaunchConfig) error {
	filename := strings.TrimSpace(cfg.ContractCarrierFile)
	if filename == "" {
		return nil
	}
	carrier, err := cfg.RequireCompiledPrompt()
	if err != nil {
		return err
	}
	contractText := carrier.LaunchSurface("runtimeCarrier")
	if strings.TrimSpace(contractText) == "" {
		return nil
	}
	if filepath.Base(filename) != filename {
		return fmt.Errorf("invalid contract carrier filename %q", filename)
	}
	path := filepath.Join(cfg.WorkDir, filename)
	content, err := renderContractCarrierFile(path, contractText)
	if err != nil {
		return fmt.Errorf("render contract carrier %s: %w", filename, err)
	}
	if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
		return fmt.Errorf("write contract carrier %s: %w", filename, err)
	}
	return nil
}

func renderContractCarrierFile(path, contractText string) (string, error) {
	existing, err := os.ReadFile(path)
	if err != nil && !os.IsNotExist(err) {
		return "", err
	}

	preserved := stripManagedContractBlock(string(existing))
	managedBlock := strings.TrimSpace(agentteamManagedContractStart + "\n\n" + strings.TrimSpace(contractText) + "\n\n" + agentteamManagedContractEnd)
	if strings.TrimSpace(preserved) == "" {
		return managedBlock + "\n", nil
	}
	return strings.TrimRight(preserved, "\n") + "\n\n" + managedBlock + "\n", nil
}

func stripManagedContractBlock(content string) string {
	start := strings.Index(content, agentteamManagedContractStart)
	end := strings.Index(content, agentteamManagedContractEnd)
	if start < 0 || end < 0 || end < start {
		return content
	}
	end += len(agentteamManagedContractEnd)
	trimmed := content[:start] + content[end:]
	return strings.Trim(trimmed, "\n")
}
