define(["require", "exports", "../bpmn_diagram", "bluebird", "bpmn-moddle"], function (require, exports, bpmn_diagram_1, BluebirdPromise, BpmnModdle) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    class ProcessDefEntityTypeService {
        constructor(datastoreService, processRepository, invoker) {
            this._datastoreService = undefined;
            this._processRepository = undefined;
            this._invoker = undefined;
            this._datastoreService = datastoreService;
            this._processRepository = processRepository;
            this._invoker = invoker;
        }
        get datastoreService() {
            return this._datastoreService;
        }
        get invoker() {
            return this._invoker;
        }
        get processRepository() {
            return this._processRepository;
        }
        async importBpmnFromFile(context, params, options) {
            const pathString = params && params.file ? params.file : null;
            if (pathString) {
                const xmlString = await this.processRepository.getXmlFromFile(pathString);
                const name = pathString.split('/').pop();
                await this.importBpmnFromXml(context, {
                    xml: xmlString,
                    path: pathString,
                    internalName: name,
                }, options);
                return { result: true };
            }
            throw new Error('file does not exist');
        }
        async importBpmnFromXml(context, params, options) {
            const overwriteExisting = options && options.hasOwnProperty('overwriteExisting') ? options.overwriteExisting : true;
            const xml = params && params.xml ? params.xml : null;
            const internalName = params && params.internalName ? params.internalName : null;
            const pathString = params && params.path ? params.path : null;
            const category = params && params.category ? params.category : null;
            const module = params && params.module ? params.module : null;
            const readonly = params && params.readonly ? params.readonly : null;
            if (!xml) {
                return;
            }
            const bpmnDiagram = await this.parseBpmnXml(xml);
            const processDef = await this.datastoreService.getEntityType('ProcessDef');
            const processes = bpmnDiagram.getProcesses();
            for (let i = 0; i < processes.length; i++) {
                const process = processes[i];
                const queryObject = {
                    operator: 'and',
                    queries: [
                        {
                            attribute: 'key',
                            operator: '=',
                            value: process.id,
                        },
                        {
                            attribute: 'draft',
                            operator: '=',
                            value: true,
                        },
                    ],
                };
                const queryParams = { query: queryObject };
                const processDefColl = await processDef.query(context, queryParams);
                let processDefEntity = processDefColl && processDefColl.length > 0 ? processDefColl.data[0] : null;
                let canSave = false;
                if (!processDefEntity) {
                    const processDefData = {
                        key: process.id,
                        defId: bpmnDiagram.definitions.id,
                        counter: 0,
                        draft: true,
                        latest: true,
                    };
                    processDefEntity = await processDef.createEntity(context, processDefData);
                    canSave = true;
                }
                else {
                    canSave = overwriteExisting;
                }
                if (!canSave) {
                    continue;
                }
                processDefEntity.name = process.name;
                processDefEntity.xml = xml;
                processDefEntity.internalName = internalName;
                processDefEntity.path = pathString;
                processDefEntity.category = category;
                processDefEntity.module = module;
                processDefEntity.readonly = readonly;
                processDefEntity.counter = processDefEntity.counter + 1;
                await this.invoker.invoke(processDefEntity, 'updateDefinitions', undefined, context, context, { bpmnDiagram: bpmnDiagram });
                await processDefEntity.save(context, { isNew: false });
            }
        }
        parseBpmnXml(xml) {
            const moddle = BpmnModdle();
            return (new BluebirdPromise((resolve, reject) => {
                moddle.fromXML(xml, (error, definitions) => {
                    if (error) {
                        reject(error);
                    }
                    else {
                        const bpmnDiagram = new bpmn_diagram_1.BpmnDiagram(definitions);
                        resolve(bpmnDiagram);
                    }
                });
            }));
        }
        async start(context, params, options) {
            if (params === undefined || params === null) {
                return;
            }
            const key = params ? params.key : undefined;
            const processId = params ? params.id : undefined;
            if (!key && !processId) {
                return null;
            }
            const version = params ? params.version : undefined;
            let processDefEntity;
            processDefEntity = await this._findLatest(context, processId, key, version);
            if (!processDefEntity) {
                processDefEntity = await this._findByKeyOnly(context, processId, key);
            }
            if (processDefEntity) {
                return this.invoker.invoke(processDefEntity, 'start', undefined, context, context, params, options);
            }
        }
        async _findLatest(context, processId, key, version) {
            let attributeName = 'key';
            let attributeValue = key;
            if (processId) {
                attributeName = 'id';
                attributeValue = processId;
            }
            const queryObjectLatestVersion = {
                operator: 'and',
                queries: [
                    {
                        attribute: attributeName,
                        operator: '=',
                        value: attributeValue,
                    },
                ],
            };
            if (version) {
                queryObjectLatestVersion.queries.push({
                    attribute: 'version',
                    operator: '=',
                    value: version,
                });
            }
            else {
                queryObjectLatestVersion.queries.push({
                    attribute: 'latest',
                    operator: '=',
                    value: true,
                });
            }
            const processDef = await this.datastoreService.getEntityType('ProcessDef');
            return processDef.findOne(context, { query: queryObjectLatestVersion });
        }
        async _findByKeyOnly(context, processId, key) {
            const processDef = await this.datastoreService.getEntityType('ProcessDef');
            const queryObjectKeyOnly = {
                attribute: (processId ? 'id' : 'key'),
                operator: '=',
                value: (processId ? processId : key),
            };
            return processDef.findOne(context, { query: queryObjectKeyOnly });
        }
        async getProcessDefinitionByKey(context, processDefinitionKey, version, versionlessFallback = false) {
            const processDefinitionEntityType = await this.datastoreService.getEntityType('ProcessDef');
            const processDefinitionByKeyQuery = {
                attribute: 'key',
                operator: '=',
                value: processDefinitionKey,
            };
            const processDefinitionByKeyAndVersionQuery = this.getQueryForVersion(processDefinitionByKeyQuery, version);
            let result = await processDefinitionEntityType.findOne(context, { query: processDefinitionByKeyAndVersionQuery });
            if ((result === undefined || result === null) && versionlessFallback) {
                result = await processDefinitionEntityType.findOne(context, { query: processDefinitionByKeyQuery });
            }
            return result;
        }
        async getProcessDefinitionById(context, processDefinitionId, version, versionlessFallback = false) {
            const processDefinitionEntityType = await this.datastoreService.getEntityType('ProcessDef');
            const processDefinitionByIdQuery = {
                attribute: 'id',
                operator: '=',
                value: processDefinitionId,
            };
            const processDefinitionByIdAndVersionQuery = this.getQueryForVersion(processDefinitionByIdQuery, version);
            let result = await processDefinitionEntityType.findOne(context, { query: processDefinitionByIdAndVersionQuery });
            if ((result === undefined || result === null) && versionlessFallback) {
                result = await processDefinitionEntityType.findOne(context, { query: processDefinitionByIdQuery });
            }
            return result;
        }
        getQueryForVersion(inputQuery, version) {
            const versionQuery = {
                operator: 'and',
                queries: [
                    Object.assign({}, inputQuery),
                ],
            };
            if (version === undefined) {
                versionQuery.queries.push({
                    attribute: 'latest',
                    operator: '=',
                    value: true,
                });
            }
            else {
                versionQuery.queries.push({
                    attribute: 'version',
                    operator: '=',
                    value: version,
                });
            }
            return versionQuery;
        }
    }
    exports.ProcessDefEntityTypeService = ProcessDefEntityTypeService;
});

//# sourceMappingURL=process_def.js.map
