/*
 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

class ReportExtend {
    constructor(fileModule) {
        this.id = 'extend';
        this.fileModule = fileModule;
    }

    init(coreContext) {
        this.coreContext = coreContext;
        this.suiteService = this.coreContext.getDefaultService('suite');
    }

    taskStart() {

    }

    taskDone() {
        const report = {
            tag: 'testsuites',
            name: 'summary_report',
            timestamp: new Date().toDateString(),
            time: '1',
            errors: 0,
            failures: 0,
            tests: 0,
            children: []
        };
        const rootSuite = this.suiteService.rootSuite;
        if (rootSuite && rootSuite.childSuites) {
            for (let testsuite of rootSuite.childSuites) {
                let suiteReport = {
                    tag: 'testsuite',
                    name: testsuite['description'],
                    errors: 0,
                    tests: 0,
                    failures: 0,
                    time: '0.1',
                    children: []
                };
                let specs = testsuite['specs'];
                for (let testcase of specs) {
                    report.tests++;
                    suiteReport.tests++;
                    let caseReport = {
                        tag: 'testcase',
                        name: testcase['description'],
                        status: 'run',
                        time: '0.0',
                        classname: testsuite['description']
                    };
                    if (testcase.error) {
                        caseReport['result'] = false;
                        caseReport['children'] = [{
                            tag: 'error',
                            type: '',
                            message: testcase.error.message
                        }];
                        report.errors++;
                        suiteReport.errors++;
                    } else if (testcase.result.failExpects.length > 0) {
                        caseReport['result'] = false;
                        let message = '';
                        testcase.result.failExpects.forEach(failExpect => {
                            message += failExpect.message || ('expect ' + failExpect.actualValue + ' ' + failExpect.checkFunc + ' ' + (failExpect.expectValue || '')) + ';';
                        });
                        caseReport['children'] = [{
                            tag: 'failure',
                            type: '',
                            message: message
                        }];
                        report.failures++;
                        suiteReport.failures++;
                    } else {
                        caseReport['result'] = true;
                    }
                    suiteReport.children.push(caseReport);
                }
                report.children.push(suiteReport);
            }
        }

        let reportXml = '<?xml version="1.0" encoding="UTF-8"?>\n' + json2xml(report);
        this.fileModule.writeText({
            uri: 'internal://app/report.xml',
            text: reportXml,
            success: function () {
                console.info('call success callback success');
            },
            fail: function (data, code) {
                console.info('call fail callback success:');
            },
            complete: function () {
                console.info('call complete callback success');
            }
        });
    }
}

function json2xml(json) {
    let tagName;
    let hasChildren = false;
    let childrenStr = '';
    let attrStr = '';
    for (let key in json) {
        if (key === 'tag') {
            tagName = json[key];
        } else if (key === 'children') {
            if (json[key].length > 0) {
                hasChildren = true;
                for (let child of json[key]) {
                    childrenStr += json2xml(child);
                }
            }
        } else {
            attrStr += ` ${key}="${json[key]}"`;
        }
    }
    let xml = `<${tagName}${attrStr}`;
    xml += hasChildren ? `>${childrenStr}</${tagName}>` : '/>';
    return xml;
}

export default ReportExtend;
