package core

import (
	"strings"
	"testing"
	"time"
)

func TestGetNextUpdate(t *testing.T) {
	date := func(year int, month time.Month, day, hour, minute int) time.Time {
		return time.Date(year, month, day, hour, minute, 0, 0, time.UTC)
	}

	expect := func(lastUpdated time.Time, spec string, expected time.Time) {
		t.Run(spec, func(t *testing.T) {
			if comment := strings.Index(spec, "#"); comment > -1 {
				spec = spec[:comment]
			}
			nextUpdate, err := GetNextUpdate(lastUpdated, spec)
			if err != nil {
				t.Fatalf("unexpected error: %v", err)
			}
			if !nextUpdate.Equal(expected) {
				t.Errorf("\nexpected: %v\n     got: %v", expected, nextUpdate)
			}
		})
	}

	expectFail := func(lastUpdated time.Time, spec string) {
		t.Run(spec, func(t *testing.T) {
			if comment := strings.Index(spec, "#"); comment > -1 {
				spec = spec[:comment]
			}
			_, err := GetNextUpdate(lastUpdated, spec)
			if err == nil {
				t.Error("expected error")
			}
		})
	}

	expect(
		date(2020, 10, 22, 12, 0),
		"every 1h#1",
		date(2020, 10, 22, 13, 0),
	)
	expect(
		date(2020, 10, 22, 12, 1),
		"every 1h#2",
		date(2020, 10, 22, 13, 0),
	)

	expect(
		date(2020, 10, 22, 11, 0),
		"every 2h30m#1",
		date(2020, 10, 22, 11, 30),
	)
	expect(
		date(2020, 10, 22, 11, 30),
		"every 2h30m#2",
		date(2020, 10, 22, 14, 0),
	)

	expectFail(
		date(2020, 10, 22, 11, 30),
		"every 3",
	)

	expect(
		date(2020, 10, 22, 12, 0),
		"at 14:00#1",
		date(2020, 10, 22, 14, 0),
	)
	expect(
		date(2020, 10, 22, 14, 0),
		"at 14:00#2",
		date(2020, 10, 23, 14, 0),
	)
	expect(
		date(2020, 10, 22, 15, 0),
		"at 14:00#3",
		date(2020, 10, 23, 14, 0),
	)

	expect(
		date(2020, 10, 22, 9, 0),
		"at 10:00,15:00#1",
		date(2020, 10, 22, 10, 0),
	)
	expect(
		date(2020, 10, 22, 12, 0),
		"at 10:00,15:00#2",
		date(2020, 10, 22, 15, 0),
	)
	expect(
		date(2020, 10, 22, 15, 0),
		"at 10:00,15:00#3",
		date(2020, 10, 23, 10, 0),
	)
	expect(
		date(2020, 10, 22, 16, 0),
		"at 10:00,15:00#4",
		date(2020, 10, 23, 10, 0),
	)

	expect(
		date(2020, 10, 22, 6, 0),
		"on Sun#1",
		date(2020, 10, 25, 0, 0),
	)
	expect(
		date(2020, 10, 25, 0, 0),
		"on Sun#2",
		date(2020, 11, 1, 0, 0),
	)

	expect(
		date(2020, 10, 19, 0, 0),
		"on Tue,Thu at 04:00#1",
		date(2020, 10, 20, 4, 0),
	)
	expect(
		date(2020, 10, 20, 3, 0),
		"on Tue,Thu at 04:00#2",
		date(2020, 10, 20, 4, 0),
	)
	expect(
		date(2020, 10, 20, 4, 0),
		"on Tue,Thu at 04:00#3",
		date(2020, 10, 22, 4, 0),
	)
	expect(
		date(2020, 10, 21, 4, 0),
		"on Tue,Thu at 04:00#4",
		date(2020, 10, 22, 4, 0),
	)
	expect(
		date(2020, 10, 22, 4, 0),
		"on Tue,Thu at 04:00#5",
		date(2020, 10, 27, 4, 0),
	)

	expect(
		date(2020, 10, 21, 12, 0),
		"on 10/22 at 12:00#1",
		date(2020, 10, 22, 12, 0),
	)
	expect(
		date(2020, 10, 22, 10, 0),
		"on 10/22 at 12:00#2",
		date(2020, 10, 22, 12, 0),
	)
	expect(
		date(2020, 10, 22, 12, 0),
		"on 10/22 at 12:00#3",
		date(2021, 10, 22, 12, 0),
	)

	expect(
		date(2020, 10, 21, 12, 0),
		"on */22#1",
		date(2020, 10, 22, 0, 0),
	)
	expect(
		date(2020, 10, 22, 0, 0),
		"on */22#2",
		date(2020, 11, 22, 0, 0),
	)

}