#include "global.h"

#include <library/cpp/testing/unittest/registar.h>

namespace {
    const TString GlobalName = "global";

    class TSimpleScheduledTask: public TGlobalScheduler::TScheduledItem<TSimpleScheduledTask> {
    private:
        using TBase = TGlobalScheduler::TScheduledItem<TSimpleScheduledTask>;
    public:
        TSimpleScheduledTask(const TString& id, TInstant executionTime, TDuration executionDuration)
            : TBase(GlobalName, id, executionTime)
            , ExecutionDuration(executionDuration)
        {
        }

        void Process(void* /*threadSpecificResource*/) override {
            THolder<TSimpleScheduledTask> cleanup(this);
            INFO_LOG << "Started " << GetId() << Endl;
            Sleep(ExecutionDuration);
            INFO_LOG << "Finished " << GetId() << Endl;
        }

    private:
        TDuration ExecutionDuration;
    };
}

Y_UNIT_TEST_SUITE(SchedulerSuite) {
    Y_UNIT_TEST(TestUniqueTasks) {
        TGlobalScheduler::Register(GlobalName);

        UNIT_ASSERT(TGlobalScheduler::Schedule(
            MakeHolder<TSimpleScheduledTask>("first", Now(), TDuration::Seconds(10))
        ));
        UNIT_ASSERT(!TGlobalScheduler::Schedule(
            MakeHolder<TSimpleScheduledTask>("first", Now(), TDuration::Seconds(10))
        ));

        UNIT_ASSERT(TGlobalScheduler::Schedule(
            MakeHolder<TSimpleScheduledTask>("second", Now(), TDuration::Seconds(10))
        ));
        UNIT_ASSERT(!TGlobalScheduler::Schedule(
            MakeHolder<TSimpleScheduledTask>("second", Now(), TDuration::Seconds(10))
        ));

        Sleep(TDuration::Seconds(20));

        UNIT_ASSERT(TGlobalScheduler::Schedule(
            MakeHolder<TSimpleScheduledTask>("first", Now(), TDuration::Seconds(10))
        ));
        UNIT_ASSERT(TGlobalScheduler::Schedule(
            MakeHolder<TSimpleScheduledTask>("second", Now(), TDuration::Seconds(10))
        ));

        TGlobalScheduler::Unregister(GlobalName);
    }
}
