"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.MagicFunction = void 0;
const core_1 = require("@midwayjs/core");
const constant_1 = require("../constant");
const core_2 = require("./core");
const definition_1 = require("./definition");
let MagicFunction = class MagicFunction {
    constructor() {
        this.type = 'function';
        this.functionMap = new Map();
        this.idInMappingPath = new Map();
        this.idInSpec = new Map();
    }
    async init(reInit = false) {
        if (reInit) {
            this.logger.info('重新初始化MagicFunction');
            this.functionMap.clear();
            this.idInMappingPath.clear();
            this.idInSpec.clear();
        }
        else {
            this.logger.info('初始化MagicFunction');
        }
        const resources = await this.magicResourceService.findByType(constant_1.RESOURCE_TYPE.Function);
        for (const resource of resources) {
            await this.add(resource);
        }
    }
    /**
     * 添加函数
     * @param resource
     */
    async add(resource) {
        const { definition, id, returnType } = resource;
        const { parameters } = definition;
        const argsName = parameters.map(p => p.key);
        await this.removeById(id);
        const mappingPath = await this.magicResourceService.getMappingPath(resource);
        const functionDefinition = (0, definition_1.FunctionDefinition)(resource.script, ...argsName);
        this.functionMap.set(mappingPath, async (...params) => {
            const ctx = this.app.createAnonymousContext();
            return await (0, definition_1.FunctionHandler)(ctx, functionDefinition, params);
        });
        this.idInMappingPath.set(id, mappingPath);
        this.idInSpec.set(id, `(functionPath: '${mappingPath}') => (${parameters
            .map(p => `${p.key}: ${this.getDataType(p.dataType)}`)
            .join(', ')}) => Promise<${this.getDataType(returnType)}>;`);
        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);
            this.idInSpec.delete(id);
            if (this.functionMap.has(mappingPath)) {
                this.functionMap.delete(mappingPath);
                this.logger.info('删除函数成功:[%s]', mappingPath);
            }
        }
    }
    /**
     * 获取数据源
     * @param functionPath
     */
    getFunction(functionPath) {
        if (this.functionMap.has(functionPath)) {
            return this.functionMap.get(functionPath);
        }
        return require(functionPath);
    }
    /**
     * 转换参数类型
     * @param dataType 参数类型
     * @private
     */
    getDataType(dataType) {
        if (dataType === 'Number') {
            return 'number';
        }
        else if (dataType === 'String') {
            return 'string';
        }
        else if (dataType === 'Boolean') {
            return 'boolean';
        }
        else if (dataType === 'Date') {
            return 'Date';
        }
        else if (dataType === 'Array') {
            return 'any[]';
        }
        else if (dataType === 'Object') {
            return '{[key: string]: any}';
        }
        throw new core_1.MidwayCommonError('不支持的参数类型：' + dataType);
    }
    /**
     * 生成定义
     */
    generateSpec() {
        return `
interface ImportFunction {
  ${[...this.idInSpec.values()].join('\r\n  ')}
}`;
    }
};
__decorate([
    (0, core_1.Inject)(),
    __metadata("design:type", core_2.MagicResourceService)
], MagicFunction.prototype, "magicResourceService", void 0);
__decorate([
    (0, core_1.Logger)('magic'),
    __metadata("design:type", Object)
], MagicFunction.prototype, "logger", void 0);
__decorate([
    (0, core_1.App)(core_1.MidwayFrameworkType.WEB_KOA),
    __metadata("design:type", Object)
], MagicFunction.prototype, "app", void 0);
MagicFunction = __decorate([
    (0, core_1.Provide)(),
    (0, core_1.Scope)(core_1.ScopeEnum.Singleton)
], MagicFunction);
exports.MagicFunction = MagicFunction;
