'use strict';

class TeamcityReporter {
    constructor(emitter, reporterOptions, options) {
        this.reporterOptions = reporterOptions;
        this.options = options;
        const events = 'start beforeIteration iteration beforeItem item beforePrerequest prerequest beforeScript script beforeRequest request beforeTest test beforeAssertion assertion console exception beforeDone done'.split(' ');
        events.forEach((e) => { if (typeof this[e] == 'function') emitter.on(e, (err, args) => this[e](err, args)) });
    }

    start(err, args) {
        console.log(`##teamcity[testSuiteStarted name='${this.escape(this.options.collection.name)}']`);
    }

    beforeItem(err, args) {
        this.currItem = {name: this.itemName(args.item), passed: true, failedAssertions: []};
        console.log(`##teamcity[testStarted name='${this.currItem.name}' captureStandardOutput='true']`);
    }

    request(err, args) {
        if (!err) {
            this.currItem.response = args.response;
        }
    }

    assertion(err, args) {
        if (err) {
            this.currItem.passed = false;
            this.currItem.failedAssertions.push(args.assertion);
        }
    }

    item(err, args) {
        if (!this.currItem.passed) {
            const msg = this.escape(this.currItem.failedAssertions.join(", "));
            const responseCode = (this.currItem.response && this.currItem.response.responseTime) || "-";
            const reason = (this.currItem.response && this.currItem.response.reason()) || "-";
            const details = this.escape(`Response code: ${responseCode}, reason: ${reason}`);
            console.log(`##teamcity[testFailed name='${this.currItem.name}' message='${msg}' details='${msg} - ${details}']`);
        }
        const duration = (this.currItem.response && this.currItem.response.responseTime) || 0;
        console.log(`##teamcity[testFinished name='${this.currItem.name}' duration='${duration}']`);
    }

    done(err, args) {
        console.log(`##teamcity[testSuiteFinished name='${this.options.collection.name}']`);
    }

    /* HELPERS */
    itemName(item) {
        const parentName = item.parent() && item.parent().name ? item.parent().name : "";
        const folderOrEmpty = parentName === this.options.collection.name ? "" : parentName + "/";
        return this.escape(folderOrEmpty + item.name);
    }

    /**
     * Escape special patterns as defined at:
     * https://confluence.jetbrains.com/display/TCD9/Build+Script+Interaction+with+TeamCity
     */
    escape(string) {
        return string
            .replace(/['|\[\]]/g, '|$&')
            .replace('\n', '|n')
            .replace('\r', '|r')
            .replace(/[\u0100-\uffff]/g, (c) => `|0x${c.charCodeAt(0).toString(16)}`);
    }
}

module.exports = TeamcityReporter;

@@ -1349,17 +1349,16 @@
 eCode = 
-(
 this.cur
@@ -1375,55 +1375,13 @@
 onse
- && this.currItem.response.responseTime) %7C%7C %22-%22
+.code
 ;%0A  
@@ -1647,23 +1647,23 @@
 e%7D' 
-message
+details
 ='$%7Bmsg%7D
 ' de
@@ -1662,44 +1662,344 @@
 msg%7D
-'
  
+- $%7B
 details
-='$%7Bmsg%7D - $%7Bdetails
+%7D'%5D%60);%0A            var responseBody;%0A%09%09%09try %7B%0A%09%09%09%09responseBody = JSON.stringify(this.currItem.response.json());%0A%09%09%09%09responseBody = this.escape(%60$%7BresponseBody%7D%60);%0A%09%09%09%09console.log(%60##teamcity%5BtestFailed responseBody ='$%7BresponseBody%7D'%60);%0A%09%09%09%7D%0A%09%09%09catch (e) %7B%0A%09%09%09%09console.log(%60##teamcity%5BtestFailed Exception : '$%7Be
 %7D'%5D%60);%0A
+%09%09%09%7D%0A
     

Fix Wrong ResponseCode issue, remove duplicated log {msg}, add ResponseBody