import * as schedule from 'node-schedule'
import { Container } from "typescript-ioc";
import { logger } from "mslib";
import { ApiError } from "./Errors";
import Contants, { IS_DEBUG, IS_PROD, IS_TEST } from './Contants'

/**
 * `Cron`时间表达式
 */
export class CronExpression {
    /**
     * 生成时间表达式, 每`{seconds}`秒
     */
    static everySecondsOn(seconds) {
        return `*/${seconds} * * * * ?`;
    }

    /**
     * 生成时间表达式, 每`{minutes}`分钟
     */
    static everyMinutesOn(minutes) {
        return `0 */${minutes} * * * ?`;
    }

    /**
     * 生成时间表达式, 每`{hours}`小时
     */
    static everyHoursOn(hours) {
        return `0 0 */${hours} * * ?`;
    }

    /**
     * 生成时间表达式, 每天`{clock}`点
     */
    static everyClockOn(clock) {
        return `0 0 ${clock} * * ?`;
    }
}

/**
 * cron计划任务装饰器(`DEBUG`环境下禁用)
 * 
 * **注：建议使用中台UTS快捷任务**
 * 
 * ```ts
 * import { CronJob, CronExpression } from "refs/nslib";
 * 
 * //去掉注释
 * //@CronJob(CronExpression.everySecondsOn(5))
 * export class SyncDataJob implements IService {
 *   async doService(): Promise<any> {
 *   
 *   }
 * }
 * ```
 * 
 * @param cronExpression cron时间表达式
 * @param description 任务描述, 仅为记录日志
 */
export function CronJob(cronExpression: string, description?: string): ClassDecorator {
    return function (target: Function) {
        if (IS_DEBUG) return;

        logger.info(`${Contants.SS_SERVICE_BASE_URL}/${Contants.P_ID}.${target.constructor.name}/1.0`, description);

        schedule.scheduleJob(cronExpression, async () => {
            try {
                let service = Container.get(target);
                await service.doService();
            } catch (error) {
                logger.error(`定时任务 ${description || target.name} 执行失败`, error);
            }
        });

        logger.info(`${target.name}(${cronExpression}) ${description || ''}`);
    }
}