package org.apache.maven.plugin.coreit;

/*
 * 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.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;

/**
 * Checks the thread-safe retrieval of components from active component collections.
 *
 * @author Benjamin Bentmann
 * @goal check-thread-safety
 * @phase validate
 */
public class CheckThreadSafetyMojo
    extends AbstractMojo
{

    /**
     * Project base directory used for manual path alignment.
     *
     * @parameter default-value="${basedir}"
     * @readonly
     */
    private File basedir;

    /**
     * The available components, as a map.
     *
     * @component role="org.apache.maven.plugin.coreit.Component"
     */
    private Map componentMap;

    /**
     * The available components, as a list.
     *
     * @component role="org.apache.maven.plugin.coreit.Component"
     */
    private List componentList;

    /**
     * The path to the properties file to create.
     *
     * @parameter property="collections.outputFile"
     */
    private File outputFile;

    /**
     * Runs this mojo.
     *
     * @throws MojoFailureException If the output file could not be created.
     */
    public void execute()
        throws MojoExecutionException
    {
        Properties componentProperties = new Properties();

        getLog().info( "[MAVEN-CORE-IT-LOG] Testing concurrent component access" );

        ClassLoader pluginRealm = getClass().getClassLoader();
        ClassLoader coreRealm = MojoExecutionException.class.getClassLoader();

        final Map map = componentMap;
        final List list = componentList;
        final List go = new Vector();
        final List exceptions = new Vector();

        Thread[] threads = new Thread[2];
        for ( int i = 0; i < threads.length; i++ )
        {
            // NOTE: The threads need to use different realms to trigger changes of the collections
            final ClassLoader cl = ( i % 2 ) == 0 ? pluginRealm : coreRealm;
            threads[i] = new Thread()
            {
                private final ClassLoader tccl = cl;

                public void run()
                {
                    getLog().info( "[MAVEN-CORE-IT-LOG] Thread " + this + " uses " + tccl );
                    Thread.currentThread().setContextClassLoader( tccl );
                    while ( go.isEmpty() )
                    {
                        // wait for start
                    }
                    for ( int j = 0; j < 10 * 1000; j++ )
                    {
                        try
                        {
                            for ( Object o : map.values() )
                            {
                                o.toString();
                            }
                            for ( Object aList : list )
                            {
                                aList.toString();
                            }
                        }
                        catch ( Exception e )
                        {
                            getLog().warn( "[MAVEN-CORE-IT-LOG] Thread " + this + " encountered concurrency issue", e );
                            exceptions.add( e );
                        }
                    }
                }
            };
            threads[i].start();
        }

        go.add( null );
        for ( Thread thread : threads )
        {
            try
            {
                thread.join();
            }
            catch ( InterruptedException e )
            {
                getLog().warn( "[MAVEN-CORE-IT-LOG] Interrupted while joining " + thread );
            }
        }

        componentProperties.setProperty( "components", Integer.toString( componentList.size() ) );
        componentProperties.setProperty( "exceptions", Integer.toString( exceptions.size() ) );

        if ( !outputFile.isAbsolute() )
        {
            outputFile = new File( basedir, outputFile.getPath() );
        }

        getLog().info( "[MAVEN-CORE-IT-LOG] Creating output file " + outputFile );

        outputFile.getParentFile().mkdirs();
        try ( OutputStream out = Files.newOutputStream( outputFile.toPath() ) )
        {
            componentProperties.store( out, "MAVEN-CORE-IT-LOG" );
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Output file could not be created: " + outputFile, e );
        }
        getLog().info( "[MAVEN-CORE-IT-LOG] Created output file " + outputFile );
    }

}
