package testutils

import (
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/require"
)

var updateGolden = flag.Bool("update", false, "update golden files")

// GetGoldenFilePath retourne le chemin vers un fichier golden (T0046)
func GetGoldenFilePath(t *testing.T, filename string) string {
	return filepath.Join("testdata", t.Name()+"_"+filename)
}

// UpdateGoldenFile met à jour un fichier golden (T0046)
func UpdateGoldenFile(t *testing.T, filename string, content []byte) {
	if !*updateGolden {
		t.Skip("Skipping golden file update (use -update flag)")
		return
	}

	path := GetGoldenFilePath(t, filename)
	err := os.MkdirAll(filepath.Dir(path), 0755)
	require.NoError(t, err)

	err = os.WriteFile(path, content, 0644)
	require.NoError(t, err)
}

// CompareGoldenFile compare le contenu avec un fichier golden (T0046)
func CompareGoldenFile(t *testing.T, filename string, actual []byte) {
	path := GetGoldenFilePath(t, filename)

	// Si update flag, mettre à jour
	if *updateGolden {
		UpdateGoldenFile(t, filename, actual)
		return
	}

	// Lire le fichier golden
	expected, err := os.ReadFile(path)
	require.NoError(t, err, "Golden file not found. Run tests with -update flag to create it.")

	require.Equal(t, string(expected), string(actual), "Golden file mismatch")
}

// CompareGoldenFileWithError compare le contenu avec un fichier golden et retourne une erreur au lieu de faire échouer le test (T0046)
// Utilisé pour tester que CompareGoldenFile échoue correctement
func CompareGoldenFileWithError(t *testing.T, filename string, actual []byte) error {
	path := GetGoldenFilePath(t, filename)

	// Si update flag, mettre à jour
	if *updateGolden {
		UpdateGoldenFile(t, filename, actual)
		return nil
	}

	// Lire le fichier golden
	expected, err := os.ReadFile(path)
	if err != nil {
		return fmt.Errorf("golden file not found. Run tests with -update flag to create it.: %w", err)
	}

	if string(expected) != string(actual) {
		return fmt.Errorf("golden file mismatch: expected %q, got %q", string(expected), string(actual))
	}

	return nil
}

// Example usage:
/*
func TestJSONOutput(t *testing.T) {
	data := map[string]interface{}{
		"key": "value",
	}
	jsonBytes, _ := json.MarshalIndent(data, "", "  ")

	CompareGoldenFile(t, "output.json", jsonBytes)
}
*/
