package org.apache.maven.plugin.surefire.booterclient.lazytestprovider;

/*
 * 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.surefire.api.booter.Command;
import org.apache.maven.surefire.api.booter.Shutdown;

import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.apache.maven.surefire.api.booter.Command.BYE_ACK;
import static org.apache.maven.surefire.api.booter.Command.NOOP;
import static org.apache.maven.surefire.api.booter.Command.SKIP_SINCE_NEXT_TEST;
import static org.apache.maven.surefire.api.booter.Command.TEST_SET_FINISHED;
import static org.apache.maven.surefire.api.booter.Command.toRunClass;
import static org.apache.maven.surefire.api.booter.Command.toShutdown;

/**
 * An {@link java.io.InputStream} that, when read, provides test class names out of a queue.
 * <br>
 * The Stream provides only one test at a time, but only after {@link #provideNewTest()} has been invoked.
 * <br>
 * After providing each test class name, followed by a newline character, a flush is performed on the
 * {@link FlushReceiver} provided by the {@link FlushReceiverProvider} that can be set using
 * {@link #setFlushReceiverProvider(FlushReceiverProvider)}.
 * <br>
 * The instance is used only in reusable forks in {@link org.apache.maven.plugin.surefire.booterclient.ForkStarter}
 * by one Thread.
 *
 * @author Andreas Gudian
 * @author Tibor Digana (tibor17)
 */
public final class TestProvidingInputStream
        extends DefaultCommandReader
{
    private final Semaphore barrier = new Semaphore( 0 );

    private final Queue<Command> commands = new ConcurrentLinkedQueue<>();

    private final AtomicBoolean closed = new AtomicBoolean();

    private final Queue<String> testClassNames;

    /**
     * C'tor
     *
     * @param testClassNames source of the tests to be read from this stream
     */
    public TestProvidingInputStream( Queue<String> testClassNames )
    {
        this.testClassNames = testClassNames;
    }

    /**
     * For testing purposes.
     */
    void testSetFinished()
    {
        if ( canContinue() )
        {
            commands.add( TEST_SET_FINISHED );
            barrier.release();
        }
    }

    @Override
    public void skipSinceNextTest()
    {
        if ( canContinue() )
        {
            commands.add( SKIP_SINCE_NEXT_TEST );
            barrier.release();
        }
    }

    @Override
    public void shutdown( Shutdown shutdownType )
    {
        if ( canContinue() )
        {
            commands.add( toShutdown( shutdownType ) );
            barrier.release();
        }
    }

    @Override
    public void noop()
    {
        if ( canContinue() )
        {
            commands.add( NOOP );
            barrier.release();
        }
    }

    @Override
    public void acknowledgeByeEventReceived()
    {
        if ( canContinue() )
        {
            commands.add( BYE_ACK );
            barrier.release();
        }
    }

    @Override
    protected Command nextCommand()
    {
        Command cmd = commands.poll();
        if ( cmd == null )
        {
            String cmdData = testClassNames.poll();
            return cmdData == null ? TEST_SET_FINISHED : toRunClass( cmdData );
        }
        else
        {
            return cmd;
        }
    }

    @Override
    protected void beforeNextCommand()
        throws IOException
    {
        awaitNextTest();
    }

    @Override
    public boolean isClosed()
    {
        return closed.get();
    }

    /**
     * Signal that a new test is to be provided.
     */
    @Override
    public void provideNewTest()
    {
        if ( canContinue() )
        {
            barrier.release();
        }
    }

    @Override
    public void close()
    {
        if ( closed.compareAndSet( false, true ) )
        {
            barrier.drainPermits();
            barrier.release();
        }
    }

    private void awaitNextTest()
        throws IOException
    {
        try
        {
            barrier.acquire();
        }
        catch ( InterruptedException e )
        {
            throw new IOException( e.getLocalizedMessage(), e );
        }
    }
}
