/*
 * Copyright (c) Madberry Oy
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */

package oap.testng;

import com.google.common.base.Throwables;
import lombok.val;
import oap.testng.casesuite.CaseContext;
import oap.util.Stream;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;

import java.util.stream.Collectors;

public class TestListener implements ITestListener {
    @Override
    public void onTestStart( ITestResult iTestResult ) {
        String method = getMethodName( iTestResult );

        System.out.println( "##teamcity[testStarted name='" + Teamcity.escape( method ) + "' captureStandardOutput='true']" );
    }

    @Override
    public void onTestSuccess( ITestResult iTestResult ) {
        String method = getMethodName( iTestResult );
        val time = iTestResult.getEndMillis() - iTestResult.getStartMillis();
        System.out.println( "##teamcity[testFinished name='" + Teamcity.escape( method ) + "' duration='" + time + "']" );
    }

    private String getClassName( ITestResult result ) {
        String className = null;
        val parameters = result.getParameters();
        if( parameters.length > 0 ) {
            if( parameters[0] != null && CaseContext.class.equals( parameters[0].getClass() ) ) {
                className = parameters[0].toString();
            }
        }

        return className != null ? className : result.getMethod().getRealClass().getSimpleName();
    }

    public String getMethodName( ITestResult iTestResult ) {
        String pStr = "";
        val parameters = iTestResult.getParameters();
        if( parameters.length > 0 ) {
            pStr = Stream.of( parameters )
                .filter( p -> p == null || !CaseContext.class.equals( p.getClass() ) )
                .map( Object::toString )
                .collect( Collectors.joining( ",", "(", ")" ) );
        } else {
            pStr = "." + iTestResult.getTestName();
        }

        return getClassName( iTestResult ) + pStr;
    }

    @Override
    public void onTestFailure( ITestResult iTestResult ) {
        String method = getMethodName( iTestResult );
        val t = iTestResult.getThrowable();
        val message = t != null ? t.getMessage() : "";
        val details = t != null ? Throwables.getStackTraceAsString( t ) : "";
        System.out.println( "##teamcity[testFailed type='comparisonFailure' name='" + Teamcity.escape( method ) + "' message='" + Teamcity.escape( message ) + "' details='" + Teamcity.escape( details ) + "']" );
        val time = iTestResult.getEndMillis() - iTestResult.getStartMillis();
        System.out.println( "##teamcity[testFinished name='" + Teamcity.escape( method ) + "' duration='" + time + "']" );
    }

    @Override
    public void onTestSkipped( ITestResult iTestResult ) {
        String method = getMethodName( iTestResult );
        System.out.println( "##teamcity[testIgnored name='" + Teamcity.escape( method ) + "' message='skipped']" );
    }

    @Override
    public void onTestFailedButWithinSuccessPercentage( ITestResult iTestResult ) {
        String method = getMethodName( iTestResult );
        val time = iTestResult.getEndMillis() - iTestResult.getStartMillis();
        System.out.println( "##teamcity[testFinished name='" + Teamcity.escape( method ) + "' duration='" + time + "']" );
    }

    @Override
    public void onStart( ITestContext context ) {
        onTestClass( context, "testSuiteStarted" );
    }

    @Override
    public void onFinish( ITestContext context ) {
        onTestClass( context, "testSuiteFinished" );
    }

    private void onTestClass( ITestContext context, String method ) {
        String name = context.getName();
        val methods = context.getAllTestMethods();
        if( methods.length > 0 ) {
            name = methods[0].getTestClass().getName();
        }
        System.out.println( "##teamcity[" + method + " name='" + Teamcity.escape( name ) + "']" );
    }
}

@@ -3,57 +3,169 @@
 %0A * 
-Copyright (c) Madberry Oy%0A * Unauthorized
+The MIT License (MIT)%0A *%0A * Copyright (c) Open Application Platform Authors%0A *%0A * Permission is hereby granted, free of charge, to any person obtaining a
  copy
-ing
+%0A *
  of 
@@ -173,83 +173,988 @@
 his 
-file, via any medium is strictly prohibited%0A * Pr
+software and associated documentation files (the %22Software%22), to deal%0A * in the Software without restriction, including without limitation the rights%0A * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell%0A * copies of the Software, and to permit persons to whom the Software is%0A * furnished to do so, subject to the following conditions:%0A *%0A * The above c
 op
+y
 ri
-etary and confidential
+ght notice and this permission notice shall be included in all%0A * copies or substantial portions of the Software.%0A *%0A * THE SOFTWARE IS PROVIDED %22AS IS%22, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR%0A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,%0A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE%0A * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER%0A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,%0A * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE%0A * SOFTWARE.
 %0A */
@@ -1814,32 +1814,122 @@
 iTestResult ) %7B%0A
+        finish( iTestResult );%0A    %7D%0A%0A    public void finish( ITestResult iTestResult ) %7B%0A
         String m
@@ -2186,16 +2186,23 @@
 private 
+static 
 String g
@@ -2723,13 +2723,8 @@
 pStr
- = %22%22
 ;%0A  
@@ -3699,32 +3699,33 @@
 ) + %22'%5D%22 );%0A
+%0A
         
 val time = i
@@ -3716,197 +3716,27 @@
     
-val time = iTestResult.getEndMillis() - iTestResult.getStartMillis();%0A        System.out.println( %22##teamcity%5BtestFinished name='%22 + Teamcity.escape( method ) + %22' duration='%22 + time + %22'%5D%22
+finish( iTestResult
  );%0A
@@ -4102,251 +4102,27 @@
     
-String method = getMethodName( iTestResult );%0A        val time = iTestResult.getEndMillis() - iTestResult.getStartMillis();%0A        System.out.println( %22##teamcity%5BtestFinished name='%22 + Teamcity.escape( method ) + %22' duration='%22 + time + %22'%5D%22
+finish( iTestResult
  );%0A
@@ -4368,32 +4368,32 @@
 shed%22 );%0A    %7D%0A%0A
-
     private void
@@ -4388,16 +4388,23 @@
 private 
+static 
 void onT

update listener