package impl

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestResolveAliyunSafeMargin(t *testing.T) {
	tests := []struct {
		name string
		raw  time.Duration
		want time.Duration
	}{
		{"valid 5m", 5 * time.Minute, 5 * time.Minute},
		{"valid 10m", 10 * time.Minute, 10 * time.Minute},
		{"valid 30m", 30 * time.Minute, 30 * time.Minute},
		{"valid 59m59s", 59*time.Minute + 59*time.Second, 59*time.Minute + 59*time.Second},
		{"zero falls back to 5m", 0, 5 * time.Minute},
		{"negative falls back to 5m", -1 * time.Minute, 5 * time.Minute},
		{"exactly 1h falls back to 5m", time.Hour, 5 * time.Minute},
		{"over 1h falls back to 5m", 90 * time.Minute, 5 * time.Minute},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			assert.Equal(t, tt.want, resolveAliyunSafeMargin(tt.raw))
		})
	}
}

func TestShouldSkipAliyunHourBoundary(t *testing.T) {
	const safeMargin = 5 * time.Minute
	baseHour := time.Date(2026, 7, 9, 10, 0, 0, 0, time.UTC)

	tests := []struct {
		name     string
		offset   time.Duration
		wantSkip bool
	}{
		{"00:00 - start of hour, no skip", 0, false},
		{"30:00 - middle of hour, no skip", 30 * time.Minute, false},
		{"54:59 - one second before danger zone, no skip", 54*time.Minute + 59*time.Second, false},
		{"55:00 - exactly at boundary (timeLeft==margin), no skip", 55 * time.Minute, false},
		{"55:01 - first second inside danger zone, skip", 55*time.Minute + 1*time.Second, true},
		{"57:30 - middle of danger zone, skip", 57*time.Minute + 30*time.Second, true},
		{"59:59 - last second of hour, skip", 59*time.Minute + 59*time.Second, true},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			now := baseHour.Add(tt.offset)
			skip, timeLeft := shouldSkipAliyunHourBoundary(now, safeMargin)
			assert.Equal(t, tt.wantSkip, skip)
			expectedLeft := time.Hour - tt.offset
			assert.Equal(t, expectedLeft, timeLeft)
		})
	}
}

func TestShouldSkipAliyunHourBoundaryDifferentMargins(t *testing.T) {
	baseHour := time.Date(2026, 7, 9, 10, 0, 0, 0, time.UTC)
	now := baseHour.Add(53 * time.Minute) // 10:53, 7 min left

	tests := []struct {
		name      string
		margin    time.Duration
		wantSkip  bool
	}{
		{"5m margin: 7m left, no skip", 5 * time.Minute, false},
		{"10m margin: 7m left, skip", 10 * time.Minute, true},
		{"7m margin: exactly at boundary, no skip", 7 * time.Minute, false},
		{"8m margin: 7m left, skip", 8 * time.Minute, true},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			skip, _ := shouldSkipAliyunHourBoundary(now, tt.margin)
			assert.Equal(t, tt.wantSkip, skip)
		})
	}
}
