import { CronJob } from 'cron';
import { CronTime } from 'cron-time-generator';
import debug from 'debug';
import { last } from 'rambda';
import { oneDayInMs, oneHourInMs } from '../../shared/utils.js';
import { appendCronLog, registerCron } from '../models/cron-status.js';
const cronLog = debug('cron');
export const setupJob = (name, when, onTick) => {
    const timePattern = when(CronTime);
    cronLog('Setting up cron for fetching', name, 'with pattern', timePattern);
    registerCron(name, timePattern);
    const j = new CronJob(timePattern, async () => {
        cronLog('Starting cron for', name);
        try {
            await onTick();
            cronLog('Done cron for', name);
            await appendCronLog(name, 'succeeded');
        }
        catch (error) {
            cronLog('Cron for ', name, 'FAILED', error);
            await appendCronLog(name, 'failed');
        }
    });
    j.start();
};
const timeSince = (date) => Date.now() - date.getTime();
const scheduleLine = (_, limit, frequency) => [limit, frequency];
export const createSchedule = ({ frequency, schedule }) => {
    const currentCallFrequency = (timeSinceLastUpdate) => {
        const sch = schedule(scheduleLine);
        const match = sch.find(([limit]) => timeSinceLastUpdate < limit);
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        return match ? match[1] : last(sch)[1];
    };
    return (lastUpdateDate) => {
        const timeSinceLastUpdate = timeSince(lastUpdateDate);
        const callFrequency = currentCallFrequency(timeSinceLastUpdate);
        const remainder = timeSince(lastUpdateDate) % callFrequency;
        return remainder >= 0 && remainder < frequency;
    };
};
export const shouldUpdate = createSchedule({
    frequency: oneHourInMs,
    schedule: s => [
        s `For the first ${oneDayInMs}, check every ${oneHourInMs}.`,
        s `Then till ${3 * oneDayInMs}, check every ${3 * oneHourInMs}.`,
        s `Then till ${6 * oneDayInMs}, check every ${12 * oneHourInMs}.`,
        s `Then till ${18 * oneDayInMs}, check every ${oneDayInMs}.`,
        s `Then till ${33 * oneDayInMs}, check every ${2 * oneDayInMs}.`,
        s `Then till ${60 * oneDayInMs}, check every ${6 * oneDayInMs}.`,
        s `Then till ${90 * oneDayInMs}, check every ${10 * oneDayInMs}.`,
    ],
});
