package org.apache.maven.plugin.surefire.extensions;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import org.apache.maven.plugin.surefire.booterclient.output.DeserializedStacktraceWriter;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.booter.ForkedProcessEventType;
import org.apache.maven.surefire.eventapi.ConsoleDebugEvent;
import org.apache.maven.surefire.eventapi.ConsoleErrorEvent;
import org.apache.maven.surefire.eventapi.ConsoleInfoEvent;
import org.apache.maven.surefire.eventapi.ConsoleWarningEvent;
import org.apache.maven.surefire.eventapi.ControlByeEvent;
import org.apache.maven.surefire.eventapi.ControlNextTestEvent;
import org.apache.maven.surefire.eventapi.ControlStopOnNextTestEvent;
import org.apache.maven.surefire.eventapi.Event;
import org.apache.maven.surefire.eventapi.JvmExitErrorEvent;
import org.apache.maven.surefire.eventapi.StandardStreamErrEvent;
import org.apache.maven.surefire.eventapi.StandardStreamErrWithNewLineEvent;
import org.apache.maven.surefire.eventapi.StandardStreamOutEvent;
import org.apache.maven.surefire.eventapi.StandardStreamOutWithNewLineEvent;
import org.apache.maven.surefire.eventapi.SystemPropertyEvent;
import org.apache.maven.surefire.eventapi.TestAssumptionFailureEvent;
import org.apache.maven.surefire.eventapi.TestErrorEvent;
import org.apache.maven.surefire.eventapi.TestFailedEvent;
import org.apache.maven.surefire.eventapi.TestSkippedEvent;
import org.apache.maven.surefire.eventapi.TestStartingEvent;
import org.apache.maven.surefire.eventapi.TestSucceededEvent;
import org.apache.maven.surefire.eventapi.TestsetCompletedEvent;
import org.apache.maven.surefire.eventapi.TestsetStartingEvent;
import org.apache.maven.surefire.extensions.CloseableDaemonThread;
import org.apache.maven.surefire.extensions.EventHandler;
import org.apache.maven.surefire.extensions.ForkNodeArguments;
import org.apache.maven.surefire.extensions.util.CountdownCloseable;
import org.apache.maven.surefire.report.RunMode;
import org.apache.maven.surefire.report.StackTraceWriter;
import org.apache.maven.surefire.report.TestSetReportEntry;
import org.apache.maven.surefire.shared.codec.binary.Base64;

import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import static java.nio.charset.StandardCharsets.US_ASCII;
import static org.apache.maven.surefire.booter.ForkedProcessEventType.MAGIC_NUMBER;
import static org.apache.maven.surefire.report.CategorizedReportEntry.reportEntry;
import static org.apache.maven.surefire.report.RunMode.MODES;

/**
 *
 */
public class EventConsumerThread extends CloseableDaemonThread
{
    private static final String[] JVM_ERROR_PATTERNS =
        {
            "could not create the java virtual machine",
            "error occurred during initialization", // of VM, of boot layer
            "error:", // general errors
            "could not reserve enough space", "could not allocate", "unable to allocate", // memory errors
            "java.lang.module.findexception" // JPMS errors
        };
    private static final String PRINTABLE_JVM_NATIVE_STREAM = "Listening for transport dt_socket at address:";
    private static final Base64 BASE64 = new Base64();

    private final ReadableByteChannel channel;
    private final EventHandler<Event> eventHandler;
    private final CountdownCloseable countdownCloseable;
    private final ForkNodeArguments arguments;
    private volatile boolean disabled;

    public EventConsumerThread( @Nonnull String threadName,
                                @Nonnull ReadableByteChannel channel,
                                @Nonnull EventHandler<Event> eventHandler,
                                @Nonnull CountdownCloseable countdownCloseable,
                                @Nonnull ForkNodeArguments arguments )
    {
        super( threadName );
        this.channel = channel;
        this.eventHandler = eventHandler;
        this.countdownCloseable = countdownCloseable;
        this.arguments = arguments;
    }

    @Override
    public void run()
    {
        try ( ReadableByteChannel stream = channel;
              CountdownCloseable c = countdownCloseable; )
        {
            decode();
        }
        catch ( IOException e )
        {
            // not needed
        }
    }

    @Override
    public void disable()
    {
        disabled = true;
    }

    @Override
    public void close() throws IOException
    {
        channel.close();
    }

    @SuppressWarnings( "checkstyle:innerassignment" )
    private void decode() throws IOException
    {
        List<String> tokens = new ArrayList<>();
        StringBuilder line = new StringBuilder();
        StringBuilder token = new StringBuilder( MAGIC_NUMBER.length() );
        ByteBuffer buffer = ByteBuffer.allocate( 1024 );
        buffer.position( buffer.limit() );
        boolean streamContinues;

        start:
        do
        {
            line.setLength( 0 );
            tokens.clear();
            token.setLength( 0 );
            FrameCompletion completion = null;
            for ( boolean frameStarted = false; streamContinues = read( buffer ); completion = null )
            {
                char c = (char) buffer.get();

                if ( c == '\n' || c == '\r' )
                {
                    printExistingLine( line );
                    continue start;
                }

                line.append( c );

                if ( !frameStarted )
                {
                    if ( c == ':' )
                    {
                        frameStarted = true;
                        token.setLength( 0 );
                        tokens.clear();
                    }
                }
                else
                {
                    if ( c == ':' )
                    {
                        tokens.add( token.toString() );
                        token.setLength( 0 );
                        completion = frameCompleteness( tokens );
                        if ( completion == FrameCompletion.COMPLETE )
                        {
                            line.setLength( 0 );
                            break;
                        }
                        else if ( completion == FrameCompletion.MALFORMED )
                        {
                            printExistingLine( line );
                            continue start;
                        }
                    }
                    else
                    {
                        token.append( c );
                    }
                }
            }

            if ( completion == FrameCompletion.COMPLETE )
            {
                Event event = toEvent( tokens );
                if ( !disabled && event != null )
                {
                    eventHandler.handleEvent( event );
                }
            }

            if ( !streamContinues )
            {
                printExistingLine( line );
                return;
            }
        }
        while ( true );
    }

    private boolean read( ByteBuffer buffer ) throws IOException
    {
        if ( buffer.hasRemaining() && buffer.position() > 0 )
        {
            return true;
        }
        else
        {
            buffer.clear();
            boolean isEndOfStream = channel.read( buffer ) == -1;
            buffer.flip();
            return !isEndOfStream;
        }
    }

    private void printExistingLine( StringBuilder line )
    {
        if ( line.length() != 0 )
        {
            ConsoleLogger logger = arguments.getConsoleLogger();
            String s = line.toString().trim();
            if ( s.contains( PRINTABLE_JVM_NATIVE_STREAM ) )
            {
                if ( logger.isDebugEnabled() )
                {
                    logger.debug( s );
                }
                else if ( logger.isInfoEnabled() )
                {
                    logger.info( s );
                }
                else
                {
                    // In case of debugging forked JVM, see PRINTABLE_JVM_NATIVE_STREAM.
                    System.out.println( s );
                }
            }
            else
            {
                if ( isJvmError( s ) )
                {
                    logger.error( s );
                }
                String msg = "Corrupted STDOUT by directly writing to native stream in forked JVM "
                    + arguments.getForkChannelId() + ".";
                File dumpFile = arguments.dumpStreamText( msg + " Stream '" + s + "'." );
                arguments.logWarningAtEnd( msg + " See FAQ web page and the dump file " + dumpFile.getAbsolutePath() );

                if ( logger.isDebugEnabled() )
                {
                    logger.debug( s );
                }
            }
        }
    }

    private Event toEvent( List<String> tokensInFrame )
    {
        Iterator<String> tokens = tokensInFrame.iterator();
        String header = tokens.next();
        assert header != null;

        ForkedProcessEventType event = ForkedProcessEventType.byOpcode( tokens.next() );

        if ( event == null )
        {
            return null;
        }

        if ( event.isControlCategory() )
        {
            switch ( event )
            {
                case BOOTERCODE_BYE:
                    return new ControlByeEvent();
                case BOOTERCODE_STOP_ON_NEXT_TEST:
                    return new ControlStopOnNextTestEvent();
                case BOOTERCODE_NEXT_TEST:
                    return new ControlNextTestEvent();
                default:
                    throw new IllegalStateException( "Unknown enum " + event );
            }
        }
        else if ( event.isConsoleErrorCategory() || event.isJvmExitError() )
        {
            Charset encoding = Charset.forName( tokens.next() );
            StackTraceWriter stackTraceWriter = decodeTrace( encoding, tokens.next(), tokens.next(), tokens.next() );
            return event.isConsoleErrorCategory()
                ? new ConsoleErrorEvent( stackTraceWriter )
                : new JvmExitErrorEvent( stackTraceWriter );
        }
        else if ( event.isConsoleCategory() )
        {
            Charset encoding = Charset.forName( tokens.next() );
            String msg = decode( tokens.next(), encoding );
            switch ( event )
            {
                case BOOTERCODE_CONSOLE_INFO:
                    return new ConsoleInfoEvent( msg );
                case BOOTERCODE_CONSOLE_DEBUG:
                    return new ConsoleDebugEvent( msg );
                case BOOTERCODE_CONSOLE_WARNING:
                    return new ConsoleWarningEvent( msg );
                default:
                    throw new IllegalStateException( "Unknown enum " + event );
            }
        }
        else if ( event.isStandardStreamCategory() )
        {
            RunMode mode = MODES.get( tokens.next() );
            Charset encoding = Charset.forName( tokens.next() );
            String output = decode( tokens.next(), encoding );
            switch ( event )
            {
                case BOOTERCODE_STDOUT:
                    return new StandardStreamOutEvent( mode, output );
                case BOOTERCODE_STDOUT_NEW_LINE:
                    return new StandardStreamOutWithNewLineEvent( mode, output );
                case BOOTERCODE_STDERR:
                    return new StandardStreamErrEvent( mode, output );
                case BOOTERCODE_STDERR_NEW_LINE:
                    return new StandardStreamErrWithNewLineEvent( mode, output );
                default:
                    throw new IllegalStateException( "Unknown enum " + event );
            }
        }
        else if ( event.isSysPropCategory() )
        {
            RunMode mode = MODES.get( tokens.next() );
            Charset encoding = Charset.forName( tokens.next() );
            String key = decode( tokens.next(), encoding );
            String value = decode( tokens.next(), encoding );
            return new SystemPropertyEvent( mode, key, value );
        }
        else if ( event.isTestCategory() )
        {
            RunMode mode = MODES.get( tokens.next() );
            Charset encoding = Charset.forName( tokens.next() );
            TestSetReportEntry reportEntry =
                decodeReportEntry( encoding, tokens.next(), tokens.next(), tokens.next(), tokens.next(),
                    tokens.next(), tokens.next(), tokens.next(), tokens.next(), tokens.next(), tokens.next() );

            switch ( event )
            {
                case BOOTERCODE_TESTSET_STARTING:
                    return new TestsetStartingEvent( mode, reportEntry );
                case BOOTERCODE_TESTSET_COMPLETED:
                    return new TestsetCompletedEvent( mode, reportEntry );
                case BOOTERCODE_TEST_STARTING:
                    return new TestStartingEvent( mode, reportEntry );
                case BOOTERCODE_TEST_SUCCEEDED:
                    return new TestSucceededEvent( mode, reportEntry );
                case BOOTERCODE_TEST_FAILED:
                    return new TestFailedEvent( mode, reportEntry );
                case BOOTERCODE_TEST_SKIPPED:
                    return new TestSkippedEvent( mode, reportEntry );
                case BOOTERCODE_TEST_ERROR:
                    return new TestErrorEvent( mode, reportEntry );
                case BOOTERCODE_TEST_ASSUMPTIONFAILURE:
                    return new TestAssumptionFailureEvent( mode, reportEntry );
                default:
                    throw new IllegalStateException( "Unknown enum " + event );
            }
        }

        throw new IllegalStateException( "Missing a branch for the event type " + event );
    }

    private static FrameCompletion frameCompleteness( List<String> tokens )
    {
        if ( !tokens.isEmpty() && !MAGIC_NUMBER.equals( tokens.get( 0 ) ) )
        {
            return FrameCompletion.MALFORMED;
        }

        if ( tokens.size() >= 2 )
        {
            String opcode = tokens.get( 1 );
            ForkedProcessEventType event = ForkedProcessEventType.byOpcode( opcode );
            if ( event == null )
            {
                return FrameCompletion.MALFORMED;
            }
            else if ( event.isControlCategory() )
            {
                return FrameCompletion.COMPLETE;
            }
            else if ( event.isConsoleErrorCategory() )
            {
                return tokens.size() == 6 ? FrameCompletion.COMPLETE : FrameCompletion.NOT_COMPLETE;
            }
            else if ( event.isConsoleCategory() )
            {
                return tokens.size() == 4 ? FrameCompletion.COMPLETE : FrameCompletion.NOT_COMPLETE;
            }
            else if ( event.isStandardStreamCategory() )
            {
                return tokens.size() == 5 ? FrameCompletion.COMPLETE : FrameCompletion.NOT_COMPLETE;
            }
            else if ( event.isSysPropCategory() )
            {
                return tokens.size() == 6 ? FrameCompletion.COMPLETE : FrameCompletion.NOT_COMPLETE;
            }
            else if ( event.isTestCategory() )
            {
                return tokens.size() == 14 ? FrameCompletion.COMPLETE : FrameCompletion.NOT_COMPLETE;
            }
            else if ( event.isJvmExitError() )
            {
                return tokens.size() == 6 ? FrameCompletion.COMPLETE : FrameCompletion.NOT_COMPLETE;
            }
        }
        return FrameCompletion.NOT_COMPLETE;
    }

    static String decode( String line, Charset encoding )
    {
        // ForkedChannelEncoder is encoding the stream with US_ASCII
        return line == null || "-".equals( line )
            ? null
            : new String( BASE64.decode( line.getBytes( US_ASCII ) ), encoding );
    }

    private static StackTraceWriter decodeTrace( Charset encoding, String encTraceMessage,
                                                 String encSmartTrimmedStackTrace, String encStackTrace )
    {
        String traceMessage = decode( encTraceMessage, encoding );
        String stackTrace = decode( encStackTrace, encoding );
        String smartTrimmedStackTrace = decode( encSmartTrimmedStackTrace, encoding );
        boolean exists = traceMessage != null || stackTrace != null || smartTrimmedStackTrace != null;
        return exists ? new DeserializedStacktraceWriter( traceMessage, smartTrimmedStackTrace, stackTrace ) : null;
    }

    static TestSetReportEntry decodeReportEntry( Charset encoding,
                                                 // ReportEntry:
                                                 String encSource, String encSourceText, String encName,
                                                 String encNameText, String encGroup, String encMessage,
                                                 String encTimeElapsed,
                                                 // StackTraceWriter:
                                                 String encTraceMessage,
                                                 String encSmartTrimmedStackTrace, String encStackTrace )
        throws NumberFormatException
    {
        if ( encoding == null )
        {
            // corrupted or incomplete stream
            return null;
        }

        String source = decode( encSource, encoding );
        String sourceText = decode( encSourceText, encoding );
        String name = decode( encName, encoding );
        String nameText = decode( encNameText, encoding );
        String group = decode( encGroup, encoding );
        StackTraceWriter stackTraceWriter =
            decodeTrace( encoding, encTraceMessage, encSmartTrimmedStackTrace, encStackTrace );
        Integer elapsed = decodeToInteger( encTimeElapsed );
        String message = decode( encMessage, encoding );
        return reportEntry( source, sourceText, name, nameText,
            group, stackTraceWriter, elapsed, message, Collections.<String, String>emptyMap() );
    }

    static Integer decodeToInteger( String line )
    {
        return line == null || "-".equals( line ) ? null : Integer.decode( line );
    }

    private static boolean isJvmError( String line )
    {
        String lineLower = line.toLowerCase();
        for ( String errorPattern : JVM_ERROR_PATTERNS )
        {
            if ( lineLower.contains( errorPattern ) )
            {
                return true;
            }
        }
        return false;
    }

    /**
     * Determines whether the frame is complete or malformed.
     */
    private enum FrameCompletion
    {
        NOT_COMPLETE,
        COMPLETE,
        MALFORMED
    }
}
