using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace Falcon.SugarApi.Test
{
    [TestClass()]
    public class CronExpressionTests
    {
        [TestMethod]
        public void CronExpressionTest() {
            var now20250213102512 = new DateTime(2025,2,13,10,25,12);

            var cron = new CronExpression("0 30 3 * * 1-5"); // 工作日凌晨3:30:00
            var nextTime = cron.GetNextOccurrence(now20250213102512);
            if(nextTime == null) {
                Assert.Fail("nextTime is null!");
                return;
            }
            Assert.IsTrue(DateToString(nextTime) == "20250214033000");
            cron = new CronExpression("");//下一秒触发
            nextTime = cron.GetNextOccurrence(now20250213102512);
            Assert.IsTrue(DateToString(nextTime) == "20250213102513");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250213102514",nextTime.ToString());

            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250213102515",nextTime.ToString());

            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250213102516",nextTime.ToString());

            cron = new CronExpression("10");//每分钟10秒时触发
            nextTime = cron.GetNextOccurrence(now20250213102512);
            Assert.IsTrue(DateToString(nextTime) == "20250213102610");

            cron = new CronExpression("10 25");//每个小时的25分10秒触发
            nextTime = cron.GetNextOccurrence(now20250213102512);
            Assert.IsTrue(DateToString(nextTime) == "20250213112510");

            cron = new CronExpression("10 25");//每个小时的25分10秒触发
            nextTime = cron.GetNextOccurrence(now20250213102512);
            Assert.IsTrue(DateToString(nextTime) == "20250213112510");

            cron = new CronExpression("10/10 25");//每个小时的25分10秒触发,只有每10秒触发一次
            nextTime = cron.GetNextOccurrence(now20250213102512);
            Assert.IsTrue(DateToString(nextTime) == "20250213102520");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250213102530");

            cron = new CronExpression("0 0 3-5");//每天凌晨3点到5点每小时触发一次
            nextTime = cron.GetNextOccurrence(now20250213102512);
            Assert.IsTrue(DateToString(nextTime) == "20250214030000");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250214040000");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250214050000");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250215030000");

            cron = new CronExpression("0 0 3-5 * * 1-5");//每个工作日凌晨3点到5点每小时触发一次
            nextTime = cron.GetNextOccurrence(now20250213102512);
            Assert.IsTrue(DateToString(nextTime) == "20250214030000");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250214040000");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250214050000");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250217030000",DateToString(nextTime));

            cron = new CronExpression("0 0/30 3-5 * * 1-5");//每个工作日凌晨3点到5点每小时触发两次,平均每半小时一次
            nextTime = cron.GetNextOccurrence(now20250213102512);
            Assert.IsTrue(DateToString(nextTime) == "20250214030000",nextTime.ToString());
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250214033000");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250214040000");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250214043000");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250214050000");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250214053000");
            nextTime = cron.GetNextOccurrence(nextTime);
            Assert.IsTrue(DateToString(nextTime) == "20250217030000");

        }

        private string? DateToString(DateTime? date) => date?.ToString("yyyyMMddHHmmss");
    }
}