"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScheduleModule = void 0;
const tslib_1 = require("tslib");
const AdaptableModuleBase_1 = require("./AdaptableModuleBase");
const ModuleConstants = tslib_1.__importStar(require("../Utilities/Constants/ModuleConstants"));
const Enums_1 = require("../AdaptableState/Common/Enums");
const ArrayExtensions_1 = tslib_1.__importDefault(require("../Utilities/Extensions/ArrayExtensions"));
const ScheduleWizard_1 = require("../View/Schedule/Wizard/ScheduleWizard");
const ScheduleSettingsSummary_1 = require("../View/Schedule/Wizard/ScheduleSettingsWizard/ScheduleSettingsSummary");
const UIHelper_1 = tslib_1.__importDefault(require("../View/UIHelper"));
const ScheduleRedux = tslib_1.__importStar(require("../Redux/ActionsReducers/ScheduleRedux"));
const getObjectTagsViewItems_1 = require("../Utilities/getObjectTagsViewItems");
const dateTimeouts = {};
const NodeSchedule = {
    scheduleJob: (date, schedule, api, fn) => {
        const timestamp = +date;
        const now = Date.now();
        const timeUntilDate = timestamp - now;
        if (timeUntilDate > 0) {
            const timeoutId = +setTimeout(() => {
                fn();
                api.eventApi.internalApi.fireScheduleTriggeredEvent(schedule);
            }, timeUntilDate);
            dateTimeouts[timestamp] = timeoutId;
        }
        return {
            cancel: () => {
                const theTimeout = dateTimeouts[timestamp];
                if (theTimeout != undefined) {
                    clearTimeout(theTimeout);
                }
            },
        };
    },
};
class ScheduleModule extends AdaptableModuleBase_1.AdaptableModuleBase {
    constructor(api) {
        super(ModuleConstants.ScheduleModuleId, ModuleConstants.ScheduleFriendlyName, 'schedule', 'SchedulePopup', 'Schedule AdapTable functionality to run at times of your choosing (e.g. run reports)', api);
        this.scheduleJobs = [];
        this.addMidnightRefreshSchedule();
    }
    onAdaptableReady() {
        this.setUpScheduleJobs();
    }
    setUpScheduleJobs() {
        this.clearAllJobs();
        //add schedules
        this.api.scheduleApi
            .getActiveReminderSchedules()
            .forEach((reminderSchedule) => {
            this.addSchedule(reminderSchedule, Enums_1.ScheduleType.Reminder);
        });
        // add Reports
        this.api.scheduleApi.getActiveReportSchedules().forEach((reportSchedule) => {
            this.addSchedule(reportSchedule, Enums_1.ScheduleType.Report);
        });
        this.api.scheduleApi
            .getActiveIPushPullSchedules()
            .forEach((iPushPullSchedule) => {
            this.addSchedule(iPushPullSchedule, Enums_1.ScheduleType.ipushpull);
        });
        this.api.scheduleApi.getActiveOpenFinSchedules().forEach((OpenFinSchedule) => {
            this.addSchedule(OpenFinSchedule, Enums_1.ScheduleType.OpenFin);
        });
        // }
    }
    addSchedule(schedule, scheduleType) {
        const date = this.getDateFromSchedule(schedule.Schedule);
        if (date != null) {
            const alertJob = NodeSchedule.scheduleJob(date, schedule, this.api, () => {
                this.api.scheduleApi.applySchedule(schedule, scheduleType);
            });
            this.scheduleJobs.push(alertJob);
        }
    }
    addMidnightRefreshSchedule() {
        const reloadSchedule = {
            Hour: 0,
            Minute: 1,
            DaysOfWeek: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
        };
        const date = this.getDateFromSchedule(reloadSchedule);
        if (date != null) {
        }
    }
    getDateFromSchedule(schedule) {
        let date = null;
        if (schedule.OneOffDate != null) {
            date = new Date(schedule.OneOffDate);
            date.setHours(schedule.Hour);
            date.setMinutes(schedule.Minute);
            date.setSeconds(0);
        }
        else {
            date = new Date();
            if (ArrayExtensions_1.default.ContainsItem(schedule.DaysOfWeek, UIHelper_1.default.getWeekDayByIndex(date.getDay()))) {
                date.setHours(schedule.Hour);
                date.setMinutes(schedule.Minute);
                date.setSeconds(0);
            }
            else {
                return null; // because it will rerun at midnight so we can get rid
            }
        }
        // add check for whether date in the past
        if (date != null && date > new Date()) {
            return date;
        }
        return null;
    }
    clearAllJobs() {
        this.scheduleJobs.forEach((j) => {
            if (j != null) {
                j.cancel();
            }
        });
        this.scheduleJobs = [];
    }
    getModuleAdaptableObjects(config) {
        const accessLevel = this.api.entitlementApi.getEntitlementAccessLevelForModule(this.moduleInfo.ModuleName);
        const exportAcessLevel = this.api.entitlementApi.getEntitlementAccessLevelForModule(ModuleConstants.ExportModuleId);
        let allSchedules = [];
        if (accessLevel !== 'Hidden') {
            allSchedules.push(...this.api.scheduleApi.getReminderSchedules(config));
        }
        if (exportAcessLevel !== 'Hidden') {
            allSchedules.push(...this.api.scheduleApi.getReportSchedules(config));
        }
        allSchedules.push(...this.api.scheduleApi.getIPushPullSchedules(config));
        allSchedules.push(...this.api.scheduleApi.getOpenFinSchedules(config));
        return allSchedules;
    }
    toView(schedule) {
        return {
            abObject: schedule,
            items: [
                {
                    name: 'Settings',
                    values: (0, ScheduleSettingsSummary_1.getScheduleSettingsValues)(schedule).map((description) => `${description.label}: ${description.value}`),
                },
                {
                    name: 'Schedule',
                    values: [UIHelper_1.default.getScheduleDescription(schedule.Schedule)],
                },
                (0, getObjectTagsViewItems_1.getObjectTagsViewItems)(schedule, this.api),
            ],
        };
    }
    toViewAll() {
        return this.getModuleAdaptableObjects({
            includeLayoutNotAssociatedObjects: this.showLayoutNotAssociatedObjects(),
        }).map((schedule) => this.toView(schedule));
    }
    getViewProperties() {
        const accessLevel = this.api.entitlementApi.getEntitlementAccessLevelForModule(this.moduleInfo.ModuleName);
        const exportAcessLevel = this.api.entitlementApi.getEntitlementAccessLevelForModule(ModuleConstants.ExportModuleId);
        const abObjectTypes = [];
        const ippApi = this.api.pluginsApi.getipushpullPluginApi();
        const openFinApi = this.api.pluginsApi.getOpenFinPluginApi();
        if (accessLevel !== 'Hidden') {
            abObjectTypes.push({
                name: 'Reminder',
                accessLevel,
            });
        }
        if (exportAcessLevel !== 'Hidden') {
            abObjectTypes.push({
                name: 'Report',
                accessLevel: exportAcessLevel,
            });
        }
        if (ippApi && ippApi.isIPushPullRunning()) {
            abObjectTypes.push({
                name: 'ipushpull',
                accessLevel,
            });
        }
        if (openFinApi && openFinApi.isOpenFinRunning()) {
            abObjectTypes.push({
                name: 'OpenFin',
                accessLevel,
            });
        }
        return {
            abObjectTypes,
            getEditAction: (schedule) => {
                let editAction = null;
                switch (schedule.ScheduleType) {
                    case Enums_1.ScheduleType.Reminder:
                        editAction = ScheduleRedux.ReminderScheduleEdit(schedule);
                        break;
                    case Enums_1.ScheduleType.Report:
                        editAction = ScheduleRedux.ReportScheduleEdit(schedule);
                        break;
                    case Enums_1.ScheduleType.ipushpull:
                        editAction = ScheduleRedux.IPushPullScheduleEdit(schedule);
                        break;
                    case Enums_1.ScheduleType.OpenFin:
                        editAction = ScheduleRedux.OpenFinScheduleEdit(schedule);
                        break;
                }
                return editAction;
            },
            getDeleteAction: (schedule) => {
                let deleteAction = null;
                switch (schedule.ScheduleType) {
                    case Enums_1.ScheduleType.Reminder:
                        deleteAction = ScheduleRedux.ReminderScheduleDelete(schedule);
                        break;
                    case Enums_1.ScheduleType.Report:
                        deleteAction = ScheduleRedux.ReportScheduleDelete(schedule);
                        break;
                    case Enums_1.ScheduleType.ipushpull:
                        deleteAction = ScheduleRedux.IPushPullScheduleDelete(schedule);
                        break;
                    case Enums_1.ScheduleType.OpenFin:
                        deleteAction = ScheduleRedux.OpenFinScheduleDelete(schedule);
                        break;
                }
                return deleteAction;
            },
            getSuspendAction: (schedule) => {
                let suspendAction = null;
                switch (schedule.ScheduleType) {
                    case Enums_1.ScheduleType.Reminder:
                        suspendAction = ScheduleRedux.ReminderScheduleSuspend(schedule);
                        break;
                    case Enums_1.ScheduleType.Report:
                        suspendAction = ScheduleRedux.ReportScheduleSuspend(schedule);
                        break;
                    case Enums_1.ScheduleType.ipushpull:
                        suspendAction = ScheduleRedux.IPushPullScheduleSuspend(schedule);
                        break;
                    case Enums_1.ScheduleType.OpenFin:
                        suspendAction = ScheduleRedux.OpenFinScheduleSuspend(schedule);
                        break;
                }
                return suspendAction;
            },
            getUnSuspendAction: (schedule) => {
                let unSuspendAction = null;
                switch (schedule.ScheduleType) {
                    case Enums_1.ScheduleType.Reminder:
                        unSuspendAction = ScheduleRedux.ReminderScheduleUnSuspend(schedule);
                        break;
                    case Enums_1.ScheduleType.Report:
                        unSuspendAction = ScheduleRedux.ReportScheduleUnSuspend(schedule);
                        break;
                    case Enums_1.ScheduleType.ipushpull:
                        unSuspendAction = ScheduleRedux.IPushPullScheduleUnSuspend(schedule);
                        break;
                    case Enums_1.ScheduleType.OpenFin:
                        unSuspendAction = ScheduleRedux.OpenFinScheduleUnSuspend(schedule);
                        break;
                }
                return unSuspendAction;
            },
            getEditWizard() {
                return ScheduleWizard_1.ScheduleWizard;
            },
        };
    }
    canBeAssociatedWithLayouts() {
        return true;
    }
}
exports.ScheduleModule = ScheduleModule;
