package miner

import (
	"testing"
	"time"

	"crypto-miner-agent/config"
	"crypto-miner-agent/stats"
)

func parseTestTime(hour, minute int) time.Time {
	return time.Date(2026, 5, 26, hour, minute, 0, 0, time.UTC)
}

func TestScheduleGuardAlways(t *testing.T) {
	guard := NewScheduleGuard(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{MiningMode: "always"}}, stats.NewReporter())
	if !guard.Allowed() {
		t.Fatal("always mode should allow mining")
	}
}

func TestScheduleGuardScheduledUsesConfigWindow(t *testing.T) {
	cfg := config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{
		MiningMode:    "scheduled",
		ScheduleStart: "21:00",
		ScheduleEnd:   "06:00",
	}}
	if !cfg.InScheduleWindow(parseTestTime(23, 0)) {
		t.Fatal("expected overnight schedule to allow mining at 23:00")
	}
}

func TestScheduleGuardScheduledDeniedOutsideWindow(t *testing.T) {
	guard := NewScheduleGuard(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{
		MiningMode:    "scheduled",
		ScheduleStart: "09:00",
		ScheduleEnd:   "17:00",
	}}, stats.NewReporter())
	if !guard.allowedAt(parseTestTime(10, 0)) {
		t.Fatal("10:00 should allow mining in 09-17 window")
	}
	if guard.allowedAt(parseTestTime(20, 0)) {
		t.Fatal("20:00 should deny mining outside 09-17 window")
	}
}

func TestScheduleGuardScheduleAlias(t *testing.T) {
	guard := NewScheduleGuard(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{
		MiningMode:    "schedule",
		ScheduleStart: "09:00",
		ScheduleEnd:   "17:00",
	}}, stats.NewReporter())
	if guard.allowedAt(parseTestTime(10, 0)) != true {
		t.Fatal("normalized schedule alias should honor daytime window at 10:00")
	}
	if guard.allowedAt(parseTestTime(3, 0)) {
		t.Fatal("normalized schedule alias should deny mining at 03:00")
	}
}

func TestScheduleGuardIdleFirstSampleNotAllowed(t *testing.T) {
	guard := NewScheduleGuard(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{
		MiningMode: "idle",
	}}, stats.NewReporter())
	// First SystemCPUPercent sample is 0 → treated as not idle.
	if guard.Allowed() {
		t.Fatal("idle mode should deny mining on first CPU sample (cpu=0)")
	}
}
