package testutils

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func TestGetGoldenFilePath(t *testing.T) {
	path := GetGoldenFilePath(t, "test.txt")
	expectedPath := filepath.Join("testdata", t.Name()+"_test.txt")

	if path != expectedPath {
		t.Errorf("Expected path %s, got %s", expectedPath, path)
	}
}

func TestGoldenFile(t *testing.T) {
	content := []byte("test content")

	// Créer le fichier golden si n'existe pas (en mode update)
	if *updateGolden {
		UpdateGoldenFile(t, "test.txt", content)
		t.Logf("Golden file created: %s", GetGoldenFilePath(t, "test.txt"))
		return
	}

	// Si le fichier n'existe pas, le créer d'abord pour le test
	goldenPath := GetGoldenFilePath(t, "test.txt")
	if _, err := os.Stat(goldenPath); os.IsNotExist(err) {
		// Créer le répertoire si nécessaire
		err := os.MkdirAll(filepath.Dir(goldenPath), 0755)
		if err != nil {
			t.Fatalf("Failed to create testdata directory: %v", err)
		}

		// Créer le fichier golden pour le test
		err = os.WriteFile(goldenPath, content, 0644)
		if err != nil {
			t.Fatalf("Failed to create golden file: %v", err)
		}

		// Nettoyer après le test
		defer os.Remove(goldenPath)
	}

	// Comparer
	CompareGoldenFile(t, "test.txt", content)
}

func TestGoldenFile_Mismatch(t *testing.T) {
	// Créer un fichier golden avec un contenu différent
	goldenPath := GetGoldenFilePath(t, "mismatch.txt")

	// Créer le répertoire si nécessaire
	err := os.MkdirAll(filepath.Dir(goldenPath), 0755)
	if err != nil {
		t.Fatalf("Failed to create testdata directory: %v", err)
	}

	// Écrire un contenu différent
	expectedContent := []byte("expected content")
	err = os.WriteFile(goldenPath, expectedContent, 0644)
	if err != nil {
		t.Fatalf("Failed to create golden file: %v", err)
	}

	// Nettoyer après le test
	defer os.Remove(goldenPath)

	// Essayer de comparer avec un contenu différent
	actualContent := []byte("actual content")

	// Ce test devrait échouer car le contenu est différent
	// Utiliser CompareGoldenFileWithError pour tester que la fonction détecte correctement les différences
	compareErr := CompareGoldenFileWithError(t, "mismatch.txt", actualContent)
	if compareErr == nil {
		t.Error("CompareGoldenFile should have failed for mismatched content")
		return
	}
	if !strings.Contains(compareErr.Error(), "golden file mismatch") {
		t.Errorf("Error should mention mismatch, got: %s", compareErr.Error())
	}
}

func TestUpdateGoldenFile(t *testing.T) {
	// Skip si le flag update n'est pas activé
	if !*updateGolden {
		t.Skip("Skipping update test (use -update flag)")
		return
	}

	content := []byte("updated content")
	UpdateGoldenFile(t, "update_test.txt", content)

	// Vérifier que le fichier a été créé
	goldenPath := GetGoldenFilePath(t, "update_test.txt")
	if _, err := os.Stat(goldenPath); os.IsNotExist(err) {
		t.Errorf("Golden file should have been created at %s", goldenPath)
	}

	// Vérifier le contenu
	fileContent, err := os.ReadFile(goldenPath)
	if err != nil {
		t.Fatalf("Failed to read golden file: %v", err)
	}

	if string(fileContent) != string(content) {
		t.Errorf("Expected content %s, got %s", string(content), string(fileContent))
	}

	// Nettoyer après le test
	os.Remove(goldenPath)
}

func TestCompareGoldenFile_NotFound(t *testing.T) {
	// Skip si le flag update est activé (car il créerait le fichier)
	if *updateGolden {
		t.Skip("Skipping not found test when -update flag is set")
		return
	}

	// Utiliser un nom de fichier qui n'existe pas
	filename := "nonexistent_file.txt"
	content := []byte("test content")

	// Ce test devrait échouer car le fichier n'existe pas
	// Utiliser CompareGoldenFileWithError pour tester que la fonction détecte correctement les fichiers manquants
	compareErr := CompareGoldenFileWithError(t, filename, content)
	if compareErr == nil {
		t.Error("CompareGoldenFile should have failed for non-existent file")
		return
	}
	if !strings.Contains(compareErr.Error(), "golden file not found") {
		t.Errorf("Error should mention file not found, got: %s", compareErr.Error())
	}
}
