package output

import (
	"encoding/csv"
	"io"
	"strconv"
	"time"

	"github.com/salvacybersec/keyhunter/pkg/engine"
)

func init() {
	Register("csv", CSVFormatter{})
}

// CSVFormatter renders findings as comma-separated values with a fixed
// header row. The id column is the zero-based index of the finding within
// the slice -- the storage-layer rowid is intentionally not used here so
// the formatter can run against in-memory results from a scan that has
// not been persisted yet. Standard encoding/csv quoting rules apply, so
// fields containing commas, quotes, or newlines are escaped automatically.
type CSVFormatter struct{}

// csvHeader is the exact, ordered header row written before any findings.
// Column order must remain stable: downstream consumers may parse by index.
// Columns: id, provider, confidence, key, source, line, detected_at, verified, verify_status
var csvHeader = []string{
	"id", "provider", "confidence", "key", "source",
	"line", "detected_at", "verified", "verify_status",
}

// Format implements the Formatter interface.
func (CSVFormatter) Format(findings []engine.Finding, w io.Writer, opts Options) error {
	cw := csv.NewWriter(w)
	if err := cw.Write(csvHeader); err != nil {
		return err
	}
	for i, f := range findings {
		key := f.KeyMasked
		if opts.Unmask {
			key = f.KeyValue
		}
		row := []string{
			strconv.Itoa(i),
			f.ProviderName,
			f.Confidence,
			key,
			f.Source,
			strconv.Itoa(f.LineNumber),
			f.DetectedAt.Format(time.RFC3339),
			strconv.FormatBool(f.Verified),
			f.VerifyStatus,
		}
		if err := cw.Write(row); err != nil {
			return err
		}
	}
	cw.Flush()
	return cw.Error()
}
