"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MagicScheduleTask = void 0;
const bull = require("@midwayjs/bull");
const core_1 = require("@midwayjs/core");
const constant_1 = require("../constant");
const core_2 = require("./core");
const definition_1 = require("./definition");
let MagicScheduleTask = class MagicScheduleTask {
    constructor() {
        this.type = 'scheduleTask';
        this.idInMappingPath = new Map();
    }
    async init(reInit = false) {
        if (reInit) {
            this.logger.info('重新初始化MagicScheduleTask');
            for (const key of this.idInMappingPath.keys()) {
                await this.removeById(key);
            }
            this.idInMappingPath.clear();
        }
        else {
            this.logger.info('初始化MagicScheduleTask');
        }
        const resources = await this.magicResourceService.findByType(constant_1.RESOURCE_TYPE.ScheduleTask);
        for (const resource of resources) {
            await this.add(resource);
        }
    }
    /**
     * 添加定时任务
     * @param resource
     */
    async add(resource) {
        var _a;
        const { id, definition, script } = resource;
        const { cron } = definition;
        await this.removeById(id);
        const mappingPath = await this.magicResourceService.getMappingPath(resource);
        this.idInMappingPath.set(id, mappingPath);
        const scheduleTaskDefinition = (0, definition_1.ScheduleTaskDefinition)(script);
        const currentQueue = this.bullFramework.ensureQueue(`scheduleTask:${mappingPath}`);
        if (this.bullConfig.bullClearRepeatJobWhenStart) {
            const jobs = await currentQueue.getRepeatableJobs();
            for (const job of jobs) {
                await currentQueue.removeRepeatableByKey(job.key);
            }
        }
        currentQueue.process((_a = this.bullConfig.defaultConcurrency) !== null && _a !== void 0 ? _a : 1, async (job) => {
            const ctx = this.bullFramework.app.createAnonymousContext({
                type: '定时任务',
                jobId: job.id,
                job,
                from: {
                    name: `scheduleTask:${mappingPath}`,
                },
            });
            ctx.logger.info(`start process job ${job.id} from scheduleTask:${mappingPath}`);
            try {
                const result = await (0, definition_1.ScheduleTaskHandler)(ctx, scheduleTaskDefinition);
                ctx.logger.info(`complete process job ${job.id} from scheduleTask:${mappingPath}`);
                return result;
            }
            catch (err) {
                ctx.logger.error(err);
                return Promise.reject(err);
            }
        });
        await this.bullFramework.runJob(currentQueue.name, {}, { repeat: { cron } });
        this.logger.info('注册定时任务:[%s]', mappingPath);
    }
    /**
     * 删除定时任务
     * @param id
     */
    async removeById(id) {
        if (this.idInMappingPath.has(id)) {
            const mappingPath = this.idInMappingPath.get(id);
            this.idInMappingPath.delete(id);
            const bullQueue = this.bullFramework.getQueue(`scheduleTask:${mappingPath}`);
            if (bullQueue) {
                await bullQueue.close();
                this.logger.info('删除定时任务成功:[%s]', mappingPath);
            }
        }
    }
};
__decorate([
    (0, core_1.Inject)(),
    __metadata("design:type", bull.Framework)
], MagicScheduleTask.prototype, "bullFramework", void 0);
__decorate([
    (0, core_1.Inject)(),
    __metadata("design:type", core_2.MagicResourceService)
], MagicScheduleTask.prototype, "magicResourceService", void 0);
__decorate([
    (0, core_1.Logger)('magic'),
    __metadata("design:type", Object)
], MagicScheduleTask.prototype, "logger", void 0);
__decorate([
    (0, core_1.Config)('bull'),
    __metadata("design:type", Object)
], MagicScheduleTask.prototype, "bullConfig", void 0);
MagicScheduleTask = __decorate([
    (0, core_1.Provide)(),
    (0, core_1.Scope)(core_1.ScopeEnum.Singleton)
], MagicScheduleTask);
exports.MagicScheduleTask = MagicScheduleTask;
