package loganalyzer

import (
	"context"
	"os"
	"path/filepath"
	"testing"
	"time"
)

func TestAnalyzeLogs_Success(t *testing.T) {
	tmpDir := t.TempDir()

	// Write mock log files
	file1 := filepath.Join(tmpDir, "log1.txt")
	err := os.WriteFile(file1, []byte(
		"[2026-07-07 10:00:00] INFO: Application started\n"+
			"[2026-07-07 10:01:00] WARNING: High memory usage\n"+
			"[2026-07-07 10:02:00] ERROR: Failed to connect to DB\n"+
			"[2026-07-07 10:03:00] INFO: Retrying connection\n",
	), 0644)
	if err != nil {
		t.Fatalf("Failed to create mock file 1: %v", err)
	}

	file2 := filepath.Join(tmpDir, "log2.txt")
	err = os.WriteFile(file2, []byte(
		"[2026-07-07 10:04:00] ERROR: Port already in use\n"+
			"[2026-07-07 10:05:00] INFO: Cleaning up resources\n"+
			"[2026-07-07 10:06:00] WARNING: Slow DB query response\n",
	), 0644)
	if err != nil {
		t.Fatalf("Failed to create mock file 2: %v", err)
	}

	ctx := context.Background()
	res, err := AnalyzeLogs(ctx, []string{file1, file2})
	if err != nil {
		t.Fatalf("AnalyzeLogs failed: %v", err)
	}

	expectedInfo := 3    // 2 in file1, 1 in file2
	expectedWarning := 2 // 1 in file1, 1 in file2
	expectedError := 2   // 1 in file1, 1 in file2

	if res.InfoCount != expectedInfo {
		t.Errorf("Expected InfoCount %d, got %d", expectedInfo, res.InfoCount)
	}
	if res.WarningCount != expectedWarning {
		t.Errorf("Expected WarningCount %d, got %d", expectedWarning, res.WarningCount)
	}
	if res.ErrorCount != expectedError {
		t.Errorf("Expected ErrorCount %d, got %d", expectedError, res.ErrorCount)
	}
}

func TestAnalyzeLogs_ContextCancelled(t *testing.T) {
	tmpDir := t.TempDir()

	// Write a mock log file
	file := filepath.Join(tmpDir, "log.txt")
	err := os.WriteFile(file, []byte("[2026-07-07 10:00:00] INFO: Application started\n"), 0644)
	if err != nil {
		t.Fatalf("Failed to create mock file: %v", err)
	}

	// Create a pre-cancelled context
	ctx, cancel := context.WithCancel(context.Background())
	cancel() // Cancel immediately

	_, err = AnalyzeLogs(ctx, []string{file})
	if err == nil {
		t.Error("Expected context cancelled error, got nil")
	} else if err != context.Canceled {
		t.Errorf("Expected error to be context.Canceled, got %v", err)
	}
}

func TestAnalyzeLogs_Timeout(t *testing.T) {
	tmpDir := t.TempDir()

	file := filepath.Join(tmpDir, "log.txt")
	err := os.WriteFile(file, []byte("[2026-07-07 10:00:00] INFO: Application started\n"), 0644)
	if err != nil {
		t.Fatalf("Failed to create mock file: %v", err)
	}

	// Create a context with microsecond timeout
	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond)
	defer cancel()

	// Give a tiny pause to ensure timeout is triggered
	time.Sleep(1 * time.Millisecond)

	_, err = AnalyzeLogs(ctx, []string{file})
	if err == nil {
		t.Error("Expected timeout error, got nil")
	} else if err != context.DeadlineExceeded && err != context.Canceled {
		t.Errorf("Expected error to be context.DeadlineExceeded, got %v", err)
	}
}
