package org.apache.maven.plugin.toolchain;

/*
 * 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.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.toolchain.MisconfiguredToolchainException;
import org.apache.maven.toolchain.ToolchainManagerPrivate;
import org.apache.maven.toolchain.ToolchainPrivate;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author mkleint
 */
@Mojo( name = "toolchain", defaultPhase = LifecyclePhase.VALIDATE )
public class ToolchainMojo
    extends AbstractMojo
{

    /**
     */
    @Component
    private ToolchainManagerPrivate toolchainManager;

    /**
     * The current build session instance. This is used for
     * toolchain manager API calls.
     */
    @Component
    private MavenSession session;

    /**
     */
    @Parameter( required = true )
    private Toolchains toolchains;

    public ToolchainMojo()
    {
    }

    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        if ( toolchains != null )
        {
            Iterator en = toolchains.getToolchainsTypes().iterator();
            List nonMatchedTypes = new ArrayList();
            while ( en.hasNext() )
            {
                try
                {
                    String type = (String) en.next();
                    getLog().info( "Type:" + type );
                    Map params = toolchains.getParams( type );
                    ToolchainPrivate[] tcs = getToolchains( type );
                    boolean matched = false;
                    for (ToolchainPrivate tc : tcs) {
                        if (tc.matchesRequirements(params)) {
                            getLog().info("Toolchain (" + type + ") matched:" + tc);
                            toolchainManager.storeToolchainToBuildContext(tc, session);
                            matched = true;
                            break;
                        }
                    }
                    if ( !matched )
                    {
                        nonMatchedTypes.add( type );
                    }
                }
                catch ( MisconfiguredToolchainException ex )
                {
                    throw new MojoExecutionException( "Misconfigured toolchains.", ex );
                }
            }
            if ( !nonMatchedTypes.isEmpty() )
            {
                //TODO add the default toolchain instance if defined??
                StringBuilder buff = new StringBuilder();
                buff.append( "Cannot find matching toolchain definitions for the following toolchain types:" );
                for (Object nonMatchedType : nonMatchedTypes) {
                    String type = (String) nonMatchedType;
                    buff.append('\n');
                    buff.append(type);
                    Map params = toolchains.getParams(type);
                    if (params.size() > 0) {
                        Iterator it2 = params.keySet().iterator();
                        buff.append(" [");
                        while (it2.hasNext()) {
                            String string = (String) it2.next();
                            buff.append(" ").append(string).append("='").append(params.get(string)).append("' ");
                        }
                        buff.append(']');
                    }
                }
                getLog().error( buff.toString() );
                throw new MojoFailureException( buff.toString()
                    + "\nPlease make sure you define the required toolchains in your ~/.m2/toolchains.xml file." );
            }
        }
        else
        {
            //can that happen?
        }
    }

    private ToolchainPrivate[] getToolchains( String type )
        throws MojoExecutionException, MisconfiguredToolchainException
    {
        Class managerClass = toolchainManager.getClass();

        try
        {
            try
            {
                // try 3.x style API
                Method newMethod =
                    managerClass.getMethod( "getToolchainsForType", new Class[] { String.class, MavenSession.class } );

                return (ToolchainPrivate[]) newMethod.invoke( toolchainManager, new Object[] { type, session } );
            }
            catch ( NoSuchMethodException e )
            {
                // try 2.x style API
                Method oldMethod = managerClass.getMethod( "getToolchainsForType", new Class[] { String.class } );

                return (ToolchainPrivate[]) oldMethod.invoke( toolchainManager, new Object[] { type } );
            }
        }
        catch ( NoSuchMethodException e )
        {
            throw new MojoExecutionException( "Incompatible toolchain API", e );
        }
        catch ( IllegalAccessException e )
        {
            throw new MojoExecutionException( "Incompatible toolchain API", e );
        }
        catch ( InvocationTargetException e )
        {
            Throwable cause = e.getCause();

            if ( cause instanceof RuntimeException )
            {
                throw (RuntimeException) cause;
            }
            if ( cause instanceof MisconfiguredToolchainException )
            {
                throw (MisconfiguredToolchainException) cause;
            }

            throw new MojoExecutionException( "Incompatible toolchain API", e );
        }
    }

}
