1package format
 2
 3import (
 4	"encoding/json"
 5	"fmt"
 6	"strings"
 7)
 8
 9// OutputFormat represents the output format type for non-interactive mode
10type OutputFormat string
11
12const (
13	// Text format outputs the AI response as plain text.
14	Text OutputFormat = "text"
15
16	// JSON format outputs the AI response wrapped in a JSON object.
17	JSON OutputFormat = "json"
18)
19
20// String returns the string representation of the OutputFormat
21func (f OutputFormat) String() string {
22	return string(f)
23}
24
25// SupportedFormats is a list of all supported output formats as strings
26var SupportedFormats = []string{
27	string(Text),
28	string(JSON),
29}
30
31// Parse converts a string to an OutputFormat
32func Parse(s string) (OutputFormat, error) {
33	s = strings.ToLower(strings.TrimSpace(s))
34
35	switch s {
36	case string(Text):
37		return Text, nil
38	case string(JSON):
39		return JSON, nil
40	default:
41		return "", fmt.Errorf("invalid format: %s", s)
42	}
43}
44
45// IsValid checks if the provided format string is supported
46func IsValid(s string) bool {
47	_, err := Parse(s)
48	return err == nil
49}
50
51// GetHelpText returns a formatted string describing all supported formats
52func GetHelpText() string {
53	return fmt.Sprintf(`Supported output formats:
54- %s: Plain text output (default)
55- %s: Output wrapped in a JSON object`,
56		Text, JSON)
57}
58
59// FormatOutput formats the AI response according to the specified format
60func FormatOutput(content string, formatStr string) string {
61	format, err := Parse(formatStr)
62	if err != nil {
63		// Default to text format on error
64		return content
65	}
66
67	switch format {
68	case JSON:
69		return formatAsJSON(content)
70	case Text:
71		fallthrough
72	default:
73		return content
74	}
75}
76
77// formatAsJSON wraps the content in a simple JSON object
78func formatAsJSON(content string) string {
79	// Use the JSON package to properly escape the content
80	response := struct {
81		Response string `json:"response"`
82	}{
83		Response: content,
84	}
85
86	jsonBytes, err := json.MarshalIndent(response, "", "  ")
87	if err != nil {
88		// In case of an error, return a manually formatted JSON
89		jsonEscaped := strings.ReplaceAll(content, "\\", "\\\\")
90		jsonEscaped = strings.ReplaceAll(jsonEscaped, "\"", "\\\"")
91		jsonEscaped = strings.ReplaceAll(jsonEscaped, "\n", "\\n")
92		jsonEscaped = strings.ReplaceAll(jsonEscaped, "\r", "\\r")
93		jsonEscaped = strings.ReplaceAll(jsonEscaped, "\t", "\\t")
94
95		return fmt.Sprintf("{\n  \"response\": \"%s\"\n}", jsonEscaped)
96	}
97
98	return string(jsonBytes)
99}