package main

import (
	"io"
	"log"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"crypto-miner-agent/config"
)

func TestShortIDLong(t *testing.T) {
	if got := shortID("abcdef1234567890"); got != "abcdef12" {
		t.Fatalf("shortID long = %q", got)
	}
}

func TestShortIDShort(t *testing.T) {
	if got := shortID("abc"); got != "abc" {
		t.Fatalf("shortID short = %q", got)
	}
}

func TestShortIDEmpty(t *testing.T) {
	if got := shortID(""); got != "pending" {
		t.Fatalf("shortID empty = %q", got)
	}
}

func TestMustInstallPathUnknown(t *testing.T) {
	cfg := config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{
		InstallBase: "custom",
	}}
	if got := mustInstallPath(cfg); got != "unknown" {
		t.Fatalf("mustInstallPath invalid cfg = %q, want unknown", got)
	}
}

func TestMustInstallPathTemp(t *testing.T) {
	cfg := config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{
		InstallBase:         "temp",
		InstallRelativePath: "test-miner-install",
		WorkerName:          "w1",
		BuildID:             "build12345678",
	}}
	got := mustInstallPath(cfg)
	if got == "unknown" || !strings.Contains(got, "test-miner-install") {
		t.Fatalf("mustInstallPath temp = %q", got)
	}
}

func TestSetupLoggingStealthDiscards(t *testing.T) {
	prev := log.Writer()
	t.Cleanup(func() { log.SetOutput(prev) })

	cfg := config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{StealthMode: true, FileLogging: true}}
	setupLogging(cfg)
	if log.Writer() != io.Discard {
		t.Fatal("stealth mode should discard log output")
	}
}

func TestSetupLoggingFileLoggingDisabled(t *testing.T) {
	prev := log.Writer()
	t.Cleanup(func() { log.SetOutput(prev) })

	cfg := config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{FileLogging: false}}
	setupLogging(cfg)
	if log.Writer() != io.Discard {
		t.Fatal("file logging disabled should discard output")
	}
}

func closeLogFileWriter() {
	if f, ok := log.Writer().(*os.File); ok {
		_ = f.Close()
	}
}

func TestSetupLoggingEnvLogFile(t *testing.T) {
	prev := log.Writer()
	dir := t.TempDir()
	logPath := filepath.Join(dir, "nested", "agent.log")
	t.Setenv("MINER_LOG_FILE", logPath)
	t.Cleanup(func() {
		closeLogFileWriter()
		log.SetOutput(prev)
		_ = os.Unsetenv("MINER_LOG_FILE")
	})

	cfg := config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{FileLogging: true}}
	setupLogging(cfg)
	if log.Writer() == io.Discard {
		t.Fatal("MINER_LOG_FILE should enable file logging")
	}
	if _, err := os.Stat(logPath); err != nil {
		t.Fatalf("expected log file at %s: %v", logPath, err)
	}
}

func TestRedirectLogCreatesFile(t *testing.T) {
	prev := log.Writer()
	dir := t.TempDir()
	path := filepath.Join(dir, "logs", "redirect.log")
	t.Cleanup(func() {
		closeLogFileWriter()
		log.SetOutput(prev)
	})

	redirectLog(path)
	log.Print("redirect test line")
	if _, err := os.Stat(path); err != nil {
		t.Fatalf("redirectLog should create %s: %v", path, err)
	}
	data, err := os.ReadFile(path)
	if err != nil {
		t.Fatal(err)
	}
	if !strings.Contains(string(data), "redirect test line") {
		t.Fatalf("log file contents: %q", data)
	}
}
