package utils

import (
	"os"
	"testing"
)

func TestFileExists(t *testing.T) {
	tempFile, err := os.CreateTemp("", "test_file")
	if err != nil {
		t.Fatalf("Failed to create temp file: %v", err)
	}
	defer os.Remove(tempFile.Name())
	defer tempFile.Close()

	if !FileExists(tempFile.Name()) {
		t.Errorf("FileExists should return true for existing file")
	}

	if FileExists("/non/existent/file") {
		t.Errorf("FileExists should return false for non-existing file")
	}
}

func TestParseKeyValue(t *testing.T) {
	tests := []struct {
		input       string
		expectedKey string
		expectedVal string
		expectedOk  bool
	}{
		{"key=value", "key", "value", true},
		{"key = value", "key", "value", true},
		{"key=\"quoted value\"", "key", "quoted value", true},
		{"key='single quoted'", "key", "single quoted", true},
		{"invalid_line", "", "", false},
		{"key=", "key", "", true},
		{"=value", "", "value", true},
	}

	for _, test := range tests {
		key, value, ok := ParseKeyValue(test.input)
		if key != test.expectedKey || value != test.expectedVal || ok != test.expectedOk {
			t.Errorf("ParseKeyValue(%q) = (%q, %q, %v), want (%q, %q, %v)",
				test.input, key, value, ok, test.expectedKey, test.expectedVal, test.expectedOk)
		}
	}
}

func TestParseInt64(t *testing.T) {
	tests := []struct {
		input    string
		expected int64
	}{
		{"123", 123},
		{"0", 0},
		{"-456", -456},
		{"invalid", 0},
		{"", 0},
		{"123.45", 0}, // Should fail for float
	}

	for _, test := range tests {
		result := ParseInt64(test.input)
		if result != test.expected {
			t.Errorf("ParseInt64(%q) = %d, want %d", test.input, result, test.expected)
		}
	}
}

func TestParseInt(t *testing.T) {
	tests := []struct {
		input    string
		expected int
	}{
		{"123", 123},
		{"0", 0},
		{"-456", -456},
		{"invalid", 0},
		{"", 0},
	}

	for _, test := range tests {
		result := ParseInt(test.input)
		if result != test.expected {
			t.Errorf("ParseInt(%q) = %d, want %d", test.input, result, test.expected)
		}
	}
}

func TestSanitizeInput(t *testing.T) {
	tests := []struct {
		input    string
		expected string
	}{
		{"clean_input", "clean_input"},
		{"  spaced  ", "spaced"},
		{"with;semicolon", ""},
		{"with&ampersand", ""},
		{"with|pipe", ""},
		{"with`backtick", ""},
		{"with$dollar", ""},
		{"with(paren", ""},
		{"with\"quote", ""},
		{"with'quote", ""},
		{"normal_text_123", "normal_text_123"},
	}

	for _, test := range tests {
		result := SanitizeInput(test.input)
		if result != test.expected {
			t.Errorf("SanitizeInput(%q) = %q, want %q", test.input, result, test.expected)
		}
	}
}

func TestFormatBytes(t *testing.T) {
	tests := []struct {
		input    int64
		expected string
	}{
		{500, "500 B"},
		{1024, "1.0 KB"},
		{1536, "1.5 KB"},
		{1048576, "1.0 MB"},
		{1073741824, "1.0 GB"},
		{0, "0 B"},
	}

	for _, test := range tests {
		result := FormatBytes(test.input)
		if result != test.expected {
			t.Errorf("FormatBytes(%d) = %q, want %q", test.input, result, test.expected)
		}
	}
}

func TestContains(t *testing.T) {
	slice := []string{"apple", "banana", "cherry"}

	tests := []struct {
		item     string
		expected bool
	}{
		{"apple", true},
		{"banana", true},
		{"cherry", true},
		{"grape", false},
		{"", false},
	}

	for _, test := range tests {
		result := Contains(slice, test.item)
		if result != test.expected {
			t.Errorf("Contains(slice, %q) = %v, want %v", test.item, result, test.expected)
		}
	}
}

func TestRemoveEmpty(t *testing.T) {
	input := []string{"apple", "", "banana", "  ", "cherry", "\t\n"}
	expected := []string{"apple", "banana", "cherry"}

	result := RemoveEmpty(input)
	if len(result) != len(expected) {
		t.Fatalf("RemoveEmpty() returned slice of length %d, want %d", len(result), len(expected))
	}

	for i, item := range result {
		if item != expected[i] {
			t.Errorf("RemoveEmpty()[%d] = %q, want %q", i, item, expected[i])
		}
	}
}
