package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

// Export only stable framework error representations, never successful responses.
// These are explicitly identified compatibility assets, not genuine Go traces.
func exportErrors(golden, output string) error {
	if err := os.MkdirAll(output, 0755); err != nil {
		return err
	}
	for _, name := range []string{"email_duplicate", "create_unknown_tag", "create_long_title"} {
		raw, err := os.ReadFile(filepath.Join(golden, name+".json"))
		if err != nil {
			return err
		}
		var obs Observation
		if err = json.Unmarshal(raw, &obs); err != nil {
			return err
		}
		if err = os.WriteFile(filepath.Join(output, name+".txt"), []byte(obs.Body.(string)), 0644); err != nil {
			return err
		}
	}
	return nil
}

// Export visible conversation only. Never export reasoning, system/developer
// instructions, tool payloads, or internal agent messages.
func exportTranscript(input, output string) error {
	f, err := os.Open(input)
	if err != nil {
		return err
	}
	defer f.Close()
	scanner := bufio.NewScanner(f)
	scanner.Buffer(make([]byte, 65536), 32<<20)
	var out strings.Builder
	out.WriteString("# AI conversation transcript\n\nVisible user and assistant messages through this export. Tool payloads, internal\nreasoning, and system/developer instructions are excluded. This is an extract,\nnot a reconstruction or a claimed complete execution trace.\n\n")
	for scanner.Scan() {
		var row struct {
			Type      string `json:"type"`
			Timestamp string `json:"timestamp"`
			Payload   struct {
				Type    string `json:"type"`
				Role    string `json:"role"`
				Channel string `json:"channel"`
				Phase   string `json:"phase"`
				Content []struct {
					Type string `json:"type"`
					Text string `json:"text"`
				} `json:"content"`
			} `json:"payload"`
		}
		if err = json.Unmarshal(scanner.Bytes(), &row); err != nil {
			return err
		}
		p := row.Payload
		if row.Type != "response_item" || p.Type != "message" {
			continue
		}
		if p.Role != "user" && p.Role != "assistant" {
			continue
		}
		if p.Role == "assistant" && p.Channel != "" && p.Channel != "commentary" && p.Channel != "final" {
			continue
		}
		if p.Role == "assistant" && p.Phase != "" && p.Phase != "commentary" && p.Phase != "final_answer" {
			continue
		}
		for _, part := range p.Content {
			if part.Type != "input_text" && part.Type != "output_text" {
				continue
			}
			if internalContext(part.Text) {
				continue
			}
			fmt.Fprintf(&out, "## %s · %s\n\n%s\n\n", p.Role, row.Timestamp, part.Text)
		}
	}
	if err = scanner.Err(); err != nil {
		return err
	}
	if err = os.MkdirAll(filepath.Dir(output), 0755); err != nil {
		return err
	}
	return os.WriteFile(output, []byte(out.String()), 0644)
}

// The session log also stores injected context as user messages. It is not
// visible conversation and can contain summaries of private reasoning.
func internalContext(s string) bool {
	for _, prefix := range []string{
		"Another language model started to solve this problem",
		"You are performing a CONTEXT CHECKPOINT COMPACTION",
		"# AGENTS.md instructions", "<environment_context>",
		"## Task and agreed scope", "<skill>", "<skills_instructions>",
	} {
		if strings.HasPrefix(strings.TrimSpace(s), prefix) {
			return true
		}
	}
	return false
}
