package cmd

import (
	"bytes"
	"encoding/json"
	"errors"
	"strings"
	"testing"

	"github.com/salvacybersec/keyhunter/pkg/engine"
	"github.com/salvacybersec/keyhunter/pkg/output"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

// TestScanOutput_FormatNamesIncludeAll guards the OUT-01..04 registration
// wiring: all four canonical formats must be reachable via output.Names().
func TestScanOutput_FormatNamesIncludeAll(t *testing.T) {
	names := output.Names()
	for _, want := range []string{"table", "json", "csv", "sarif"} {
		assert.Contains(t, names, want)
	}
}

// TestRenderScanOutput_UnknownReturnsError verifies that renderScanOutput
// surfaces ErrUnknownFormat and includes the valid-format list in the message.
func TestRenderScanOutput_UnknownReturnsError(t *testing.T) {
	err := renderScanOutput(nil, "bogus", false, &bytes.Buffer{})
	require.Error(t, err)
	assert.True(t, errors.Is(err, output.ErrUnknownFormat), "error should wrap output.ErrUnknownFormat, got: %v", err)
	assert.Contains(t, err.Error(), "valid:")
}

// TestRenderScanOutput_JSONSucceeds ensures the JSON formatter is wired up and
// produces a valid empty JSON array for zero findings.
func TestRenderScanOutput_JSONSucceeds(t *testing.T) {
	var buf bytes.Buffer
	err := renderScanOutput([]engine.Finding{}, "json", false, &buf)
	require.NoError(t, err)
	var out []any
	require.NoError(t, json.Unmarshal(buf.Bytes(), &out))
	assert.Len(t, out, 0)
}

// TestRenderScanOutput_TableEmpty ensures the default table formatter is
// wired up and emits the canonical empty-state message.
func TestRenderScanOutput_TableEmpty(t *testing.T) {
	var buf bytes.Buffer
	err := renderScanOutput(nil, "table", false, &buf)
	require.NoError(t, err)
	assert.True(t, strings.Contains(buf.String(), "No API keys found"))
}
