"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const typeorm_1 = require("typeorm");
const integration_base_1 = require("@things-factory/integration-base");
const utils_1 = require("@things-factory/utils");
const env_1 = require("@things-factory/env");
const auth_base_1 = require("@things-factory/auth-base");
const analysis_1 = require("../../service/analysis/analysis");
const process_1 = require("../../service/process/process");
const shell_1 = require("@things-factory/shell");
const STEDCONFIG = env_1.config.get('sted', {});
/*
TODO: 모듈 이름과 파라미터 이름에 대한 자동화를 어떻게 헤야할지??

*/
const moduleNames = {
    'ahp-direct-prl': '직화식 이중효용 흡수식 냉동기(병렬)',
    'ahp-direct-srl': '직화식 이중효용 흡수식 냉동기(직렬)',
    'ahp-low-tw': '저온수 2단 흡수식 냉동기',
    'ahp-mid-tw': '중온수 2단 흡수식 냉동기',
    'ahp-stm-1efc': '스팀구동 흡수식 냉동기(1중)',
    'ahp-stm-2efc': '스팀구동 흡수식 냉동기(2중)',
    'boiler-ot': '관류식 보일러',
    'boiler-st': '노통연관식 보일러',
    'boiler-wtr': '수관식 보일러',
    'cmb-hot-air': '열풍용 연소기',
    'cmb-hvol': '보일러용 연소기(고체적 열부하형)',
    'cmb-mlvol': '보일러용 연소기(중저체적 열부하형)',
    'cmb-nozmix': '노즐믹스 연소기',
    'cmb-oxht': '고온형 산소부화 연소기',
    'cmb-oxln': '저 Nox형 산소부화 연소기',
    'cmb-porrh': '급속가열형 다공체 연소기',
    'cmb-poruh': '균일가열형 다공체 연소기',
    'cmb-radln': '저 Nox형 복사관 연소기',
    'cmb-radut': '균일온도형 복사관 연소기',
    'cmb-surf': '표면연소 연소기',
    'dryer-band': '통기밴드 건조기',
    'dryer-drum': '드럼 건조기',
    'dryer-rotary': '회전식 건조기',
    'es-electricity': '물질 공급 (전기)',
    'es-heat': '물질 공급 (열)',
    fmix: '유체 혼합기2',
    fmix3: '유체 혼합기3',
    fsplit: '유체 분배기2',
    fsplit3: '유체 분배기3',
    'fur-contforg': '연속단조로 공업로',
    'fur-rhk': 'RHK 공업로',
    furnace: '공업로',
    heater: '히터',
    hx: '열교환기',
    'me-dried-matter': '물질 배출 (건조물)',
    'me-flu': '물질 배출 (배기)',
    'me-metal': '물질 배출 (금속제품)',
    'me-hot-matter': '물질 배출 (고온물질)',
    'me-hot-steel': '물질 배출 (고온금속)',
    'me-rhk': '물질 배출 (RHK)',
    'me-sewerage': '물질 배출 (하수)',
    'me-stack': '물질 배출 (스택)',
    'me-steam': '물질 배출 (스팀)',
    'me-steel': '물질 배출 (금속제품)',
    'ms-air': '물질 공급 (공기)',
    'ms-lpg': '물질 공급 (액화석유가스)',
    'ms-mixed-gas': '물질 공급 (혼합가스)',
    'ms-metal': '물질 공급 (금속재)',
    'ms-ng': '물질 공급 (천연가스)',
    'ms-pure-gas': '물질 공급 (순수가스)',
    'ms-paper': '물질 공급 (종이)',
    'ms-rhk': '물질 공급 (RHK)',
    'ms-steam': '물질 공급 (스팀)',
    'ms-steel': '물질 공급 (금속재)',
    'ms-textile': '물질 공급 (섬유)',
    'ms-water': '물질 공급 (물)',
    'ms-wet-textile': '물질 공급 (습윤 섬유)',
    plc: 'plc',
    'post-tr-bf': '집진기',
    'post-tr-cyc': '싸이클론',
    'post-tr-hx-gas': '가스 열교환기',
    'post-tr-scr': '탈질반응기',
    streamline: '스트림라인',
    recycle: '재순환 노드',
    'turbo-blower': '송풍기',
    'turbo-pump': '펌프',
    'vchp-basic': '증기압축식 히트펌프 (기본형)',
    'vchp-cscd': '증기압축식 히트펌프 (캐스캐이드형)',
    'vchp-ihx': '증기압축식 히트펌프 (내부열교환기형)',
    'vchp-inject': '증기압축식 히트펌프 (인젝트형)',
    'vchp-steam': '증기압축식 히트펌프 (스팀형)',
    'ud-q': '사용자 정의 가열/냉각'
};
const parameterNames = {
    'air-pulsing-interval': '공기 펄스 주기',
    'air-pulsing-time': '공기 펄스 시간',
    'ambient-temperature': '주변 온도(상온)',
    'back-filter-pressure-drop': '백필터 압력 강하',
    'c2h6-mole-fraction': 'C2H6 몰분율',
    'c3h8-mole-fraction': 'C3H8 몰분율',
    'c4h10-mole-fraction': 'C4H10 몰분율',
    'ch4-mole-fraction': 'CH4 몰분율',
    'co2-mole-fraction': 'CO2 몰분율',
    'cold-pressure-drop': '저온 유체 차압',
    'cyclone-pressure-drop': '싸이클론 압력 강하',
    'dont-know-mvf': '질량/체적 유량을 모릅니다.',
    'dont-know-t': '온도를 모릅니다.',
    'dont-know-mc': '함수율을 모릅니다.',
    'energy-efficiency': '에너지 효율',
    fuel: '연료',
    'heat-loss': '손실열',
    'heat-loss-ratio': '열손실율',
    'heat-transfer-efficiency': '열전달 효율',
    'heat-transfer-rate': '열전달량',
    'hot-pressure-drop': '고온 유체 차압',
    'hx-type': '열교환기 유형',
    'in-heat': '입력 열전달량',
    'm-steam': '증기 질량유량',
    'material-pressure': '건조물 압력',
    'material-temperature': '건조물 온도',
    'moisture-content': '함수율',
    'n2-mole-fraction': 'N2 몰분율',
    'ng-mass': '천연가스 질량유량',
    'ng-pressure': '천연가스 압력',
    'ng-temperature': '천연가스 온도',
    'ng-volume': '천연가스 체적유량',
    'nox-conversion': 'NOx 전환율',
    'o2-mole-fraction': 'O2 몰분율',
    'operation-pressure': '운전 압력',
    'operation-temperature': '운전 온도',
    'out-electricity': '출력 전력',
    'out-heat': '열전달량',
    'out-temperature': '출구 온도',
    outleth: '출력 비엔탈피',
    outletm: '출력 질량유량',
    outletp: '출력 압력',
    outletT: '출력 온도',
    outletvf: '출력 체적유량',
    outletY: '출력 조성',
    'outlet-gas-t': '출력 가스 온도',
    'outlet-solid-t': '출력 고체 온도',
    'power-consumtion': '소모전력',
    pressure: '압력',
    'pressure-drop-1': '첫번째 출력 압력 강하',
    'pressure-drop-2': '두번째 출력 압력 강하',
    'pressure-drop-3': '세번째 출력 압력 강하',
    'pressure-increase': '압력 증가',
    purpose: '목적',
    'scr-operation-pressure': 'SCR 운전 압력',
    'scr-operation-temperature': 'SCR 운전 온도',
    'sensible-heat-ratio': '공기 현열비',
    'specific-heat': '비열',
    'split-ratio': '분배율',
    'split-ratio1': '분배율1 (입력에서 출력 #1)',
    'split-ratio2': '분배율2 (입력에서 출력 #2)',
    'split-ratio3': '분배율3 (입력에서 출력 #3)',
    'T-makeup': '메이크업 온도',
    'T-outcond': '응축기 출력 온도',
    'T-steam': '증기 온도',
    'target-MC': '목표 함수율',
    'recirculation-ratio': '열풍 재순환율',
    throughput: '처리량',
    'total-mass': '총 질량유량',
    'ms-metal.total-mass': '투입량',
    'tube-temperature': '복사관 출구 온도',
    udq: '가열/냉각 열량',
    'unknown-flag': '미지수 플랙',
    'wet-bulb-temperature': '공기 습구온도',
    'metal-name': '금속 이름',
    'choose-outgas-temp-or-outsolid-temp': '출력 고체 온도를 지정할 경우 선택하세요.',
    'fur-efficiency': '공업로 효율',
    'init-fluid-Y': '초기 조성',
    'init-fluid-m': '초기 질량유량',
    'init-fluid-T': '초기 온도',
    'init-fluid-p': '초기 압력'
};
const streamDataKey = {
    h: '비엔탈피',
    m: '질량유량',
    p: '압력',
    T: '온도',
    vf: '체적유량',
    Y: '조성',
    MC: '함수율'
};
async function ProcessReport(step, context) {
    var _a, _b;
    var { params: { process: processObject, processAccessor } } = step;
    var { domain, user, data, variables } = context;
    const processId = processAccessor ? (0, utils_1.access)(processAccessor, data) : processObject === null || processObject === void 0 ? void 0 : processObject.id;
    const analysis = await (0, shell_1.getRepository)(analysis_1.Analysis).findOne({ where: { process: { id: processId } } });
    const process = await (0, shell_1.getRepository)(process_1.Process).findOne({
        where: { domain: { id: (0, typeorm_1.In)([domain.id, domain.parentId].filter(Boolean)) }, id: processId }
    });
    // node type 한글로 변환
    let stedNodes = ((_a = analysis.result) === null || _a === void 0 ? void 0 : _a.stedNodes) || [];
    stedNodes.length !== 0 &&
        stedNodes.forEach(stedNode => {
            // 타입을 의미있는 한글 이름으로 변환
            stedNode.type = moduleNames[`${stedNode.type}`] || stedNode.type;
            // 불필요한 파라미터 제거하고, 파라미터 키를 의미있는 한글 이름으로 변환
            const unnecessaryParams = [
                'type',
                'left',
                'top',
                'width',
                'height',
                'equipment',
                'fillStyle',
                'textBaseline',
                'text',
                'fontFamily',
                'refid',
                'rotation',
                'lineWidth',
                'strokeStyle'
            ];
            Object.keys(stedNode.params).forEach(key => {
                if (unnecessaryParams.includes(key)) {
                    delete stedNode.params[key];
                }
            });
            // 파라미터 키를 의미있는 한글 이름으로 변환
            // label의 변수명이 kebab-case이기 때문에 이를 감안해서 변경.
            let updatedParams = {};
            const convertToKebabCase = str => {
                return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
            };
            Object.keys(stedNode.params).forEach(key => {
                const convKey = convertToKebabCase(key);
                parameterNames.hasOwnProperty(convKey) && (updatedParams[parameterNames[convKey]] = stedNode.params[key]);
            });
            stedNode.params = updatedParams;
            // inlet, outlet의 데이터 키를 의미있는 한글 이름으로 변환
            stedNode.inlets.map(inlet => {
                let updateData = {};
                Object.keys(inlet === null || inlet === void 0 ? void 0 : inlet.data).forEach(inletDatakey => {
                    streamDataKey.hasOwnProperty(inletDatakey) &&
                        (updateData[streamDataKey[inletDatakey]] = inlet.data[inletDatakey]);
                });
                inlet.data = updateData;
            });
            stedNode.outlets.map(outlet => {
                let updateData = {};
                Object.keys(outlet === null || outlet === void 0 ? void 0 : outlet.data).forEach(outletDatakey => {
                    streamDataKey.hasOwnProperty(outletDatakey) &&
                        (updateData[streamDataKey[outletDatakey]] = outlet.data[outletDatakey]);
                });
                outlet.data = updateData;
            });
        });
    // get a creator
    const creator = await (0, shell_1.getRepository)(auth_base_1.User).findOne({ where: { id: process.creatorId } });
    const reportInput = Object.assign({ processName: process.name, processUser: creator === null || creator === void 0 ? void 0 : creator.name, processDate: process.createdAt, smartGuides: ((_b = analysis.result) === null || _b === void 0 ? void 0 : _b.smartGuides) || [] }, analysis.result);
    /*
    TODO: 레포트 입력 데이터를 기존 stedNodes 데이터를 구체화함으로서, 레포트의 질을 높이는 작업이 필요.
        
    */
    const response = await fetch(`${STEDCONFIG.url}/process-report`, {
        method: 'POST',
        headers: {
            Accept: '*/*',
            'Content-Type': 'application/json',
            Connection: 'keep-alive'
        },
        body: JSON.stringify(reportInput)
    });
    const processResult = await response.json();
    return {
        data: processResult === null || processResult === void 0 ? void 0 : processResult.result
    };
}
ProcessReport.parameterSpec = [
    {
        type: 'string',
        name: 'processAccessor',
        label: 'process-accessor'
    },
    {
        type: 'resource-object',
        name: 'process',
        label: 'process',
        property: {
            queryName: 'processes'
        }
    }
];
ProcessReport.help = 'integration/task/process-analysis';
ProcessReport.connectorFree = true;
integration_base_1.TaskRegistry.registerTaskHandler('process-report', ProcessReport);
//# sourceMappingURL=process-report.js.map