package org.apache.maven.plugins.enforcer;

/*
 * 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 java.util.Iterator;

import org.apache.maven.enforcer.rule.api.EnforcerRule;
import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
import org.apache.maven.model.Activation;
import org.apache.maven.model.ActivationOS;
import org.apache.maven.model.Profile;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.model.profile.activation.ProfileActivator;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.util.Os;
import org.codehaus.plexus.util.StringUtils;

/**
 * This rule checks that the OS is allowed by combinations of family, name, version and cpu architecture. The behavior
 * is exactly the same as the Maven Os profile activation so the same values are allowed here.
 *
 * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
 */
public class RequireOS
    extends AbstractStandardEnforcerRule
{
    private ProfileActivator activator;

    /**
     * The OS family type desired<br />
     * Possible values:
     * <ul>
     * <li>dos</li>
     * <li>mac</li>
     * <li>netware</li>
     * <li>os/2</li>
     * <li>tandem</li>
     * <li>unix</li>
     * <li>windows</li>
     * <li>win9x</li>
     * <li>z/os</li>
     * <li>os/400</li>
     * </ul>
     * 
     * @see {@link #setFamily(String)}
     * @see {@link #getFamily()}
     */
    private String family = null;

    /**
     * The OS name desired.
     *
     * @see {@link #setName(String)}
     * @see {@link #getName()}
     */
    private String name = null;

    /**
     * The OS version desired.
     * 
     * @see {@link #setVersion(String)}
     * @see {@link #getVersion()}
     */
    private String version = null;

    /**
     * The OS architecture desired.
     * 
     * @see {@link #setArch(String)}
     * @see {@link #getArch()}
     */
    private String arch = null;

    /**
     * Display detected OS information.
     * 
     * @see {@link #setDisplay(boolean)}
     * @see {@link #isDisplay()}
     */
    private boolean display = false;

    /**
     * Instantiates a new RequireOS.
     */
    public RequireOS()
    {

    }
    
    // For testing
    RequireOS( ProfileActivator activator ) 
    {
        this.activator = activator;
    }
    

    @Override
    public void execute( EnforcerRuleHelper helper )
        throws EnforcerRuleException
    {

        displayOSInfo( helper.getLog(), display );

        if ( allParamsEmpty() )
        {
            throw new EnforcerRuleException( "All parameters can not be empty. "
                + "You must pick at least one of (family, name, version, arch) "
                + "or use -Denforcer.os.display=true to see the current OS information." );
        }
        
        try
        {
            activator = helper.getComponent( ProfileActivator.class, "os" );
        }
        catch ( ComponentLookupException e )
        {
            throw new EnforcerRuleException( e.getMessage() );
        }

        if ( isValidFamily( this.family ) )
        {
            if ( !isAllowed() )
            {
                String message = getMessage();
                if ( StringUtils.isEmpty( message ) )
                {
                    //@formatter:off
                    message =
                        ( "OS Arch: " 
                            + Os.OS_ARCH + " Family: " 
                            + Os.OS_FAMILY + " Name: " 
                            + Os.OS_NAME + " Version: "
                            + Os.OS_VERSION + " is not allowed by" + ( arch != null ? " Arch=" + arch : "" )
                            + ( family != null ? " Family=" + family : "" ) 
                            + ( name != null ? " Name=" + name : "" ) 
                            + ( version != null ? " Version=" + version : "" ) );
                    //@formatter:on
                }
                throw new EnforcerRuleException( message );
            }
        }
        else
        {
            final int minimumBufferSize = 50;
            StringBuilder buffer = new StringBuilder( minimumBufferSize );
            Iterator<?> iter = Os.getValidFamilies().iterator();
            while ( iter.hasNext() )
            {
                buffer.append( iter.next() );
                buffer.append( ", " );
            }
            String help = StringUtils.stripEnd( buffer.toString().trim(), "." );
            throw new EnforcerRuleException( "Invalid Family type used. Valid family types are: " + help );
        }
    }

    /**
     * Log the current OS information.
     *
     * @param log the log
     * @param info the info
     */
    public void displayOSInfo( Log log, boolean info )
    {
        String string =
            "OS Info: Arch: " + Os.OS_ARCH + " Family: " + Os.OS_FAMILY + " Name: " + Os.OS_NAME + " Version: "
                + Os.OS_VERSION;

        if ( !info )
        {
            log.debug( string );
        }
        else
        {
            log.info( string );
        }
    }

    /**
     * Helper method to determine if the current OS is allowed based on the injected values for family, name, version
     * and arch.
     *
     * @return true if the version is allowed.
     */
    public boolean isAllowed()
    {
        return activator.isActive( createProfile(), null, null );
    }

    /**
     * Helper method to check that at least one of family, name, version or arch is set.
     *
     * @return true if all parameters are empty.
     */
    public boolean allParamsEmpty()
    {
        // CHECKSTYLE_OFF: LineLength
        return ( StringUtils.isEmpty( family ) && StringUtils.isEmpty( arch ) && StringUtils.isEmpty( name ) && StringUtils.isEmpty( version ) );
        // CHECKSTYLE_ON: LineLength
    }

    /**
     * Creates a Profile object that contains the activation information.
     *
     * @return a properly populated profile to be used for OS validation.
     */
    private Profile createProfile()
    {
        Profile profile = new Profile();
        profile.setActivation( createActivation() );
        return profile;
    }

    /**
     * Creates an Activation object that contains the ActivationOS information.
     *
     * @return a properly populated Activation object.
     */
    private Activation createActivation()
    {
        Activation activation = new Activation();
        activation.setActiveByDefault( false );
        activation.setOs( createOsBean() );
        return activation;
    }

    /**
     * Creates an ActivationOS object containing family, name, version and arch.
     *
     * @return a properly populated ActivationOS object.
     */
    private ActivationOS createOsBean()
    {
        ActivationOS os = new ActivationOS();

        os.setArch( arch );
        os.setFamily( family );
        os.setName( name );
        os.setVersion( version );

        return os;
    }

    /**
     * Helper method to check if the given family is in the following list:
     * <ul>
     * <li>dos</li>
     * <li>mac</li>
     * <li>netware</li>
     * <li>os/2</li>
     * <li>tandem</li>
     * <li>unix</li>
     * <li>windows</li>
     * <li>win9x</li>
     * <li>z/os</li>
     * <li>os/400</li>
     * </ul>
     * Note: '!' is allowed at the beginning of the string and still considered valid.
     *
     * @param theFamily the family to check.
     * @return true if one of the valid families.
     */
    public boolean isValidFamily( String theFamily )
    {

        // in case they are checking !family
        theFamily = StringUtils.stripStart( theFamily, "!" );

        return ( StringUtils.isEmpty( theFamily ) || Os.getValidFamilies().contains( theFamily ) );
    }

    /**
     * Gets the arch.
     *
     * @return the arch
     */
    public String getArch()
    {
        return this.arch;
    }

    /**
     * Sets the arch.
     *
     * @param theArch the arch to set
     */
    public void setArch( String theArch )
    {
        this.arch = theArch;
    }

    /**
     * Gets the family.
     *
     * @return the family
     */
    public String getFamily()
    {
        return this.family;
    }

    /**
     * Sets the family.
     *
     * @param theFamily the family to set
     */
    public void setFamily( String theFamily )
    {
        this.family = theFamily;
    }

    /**
     * Gets the name.
     *
     * @return the name
     */
    public String getName()
    {
        return this.name;
    }

    /**
     * Sets the name.
     *
     * @param theName the name to set
     */
    public void setName( String theName )
    {
        this.name = theName;
    }

    /**
     * Gets the version.
     *
     * @return the version
     */
    public String getVersion()
    {
        return this.version;
    }

    /**
     * Sets the version.
     *
     * @param theVersion the version to set
     */
    public void setVersion( String theVersion )
    {
        this.version = theVersion;
    }

    /**
     * @param display The value for the display.
     */
    public final void setDisplay( boolean display )
    {
        this.display = display;
    }

    public final boolean isDisplay()
    {
        return display;
    }

    @Override
    public String getCacheId()
    {
        // return the hashcodes of all the parameters
        StringBuffer b = new StringBuffer();
        if ( StringUtils.isNotEmpty( version ) )
        {
            b.append( version.hashCode() );
        }
        if ( StringUtils.isNotEmpty( name ) )
        {
            b.append( name.hashCode() );
        }
        if ( StringUtils.isNotEmpty( arch ) )
        {
            b.append( arch.hashCode() );
        }
        if ( StringUtils.isNotEmpty( family ) )
        {
            b.append( family.hashCode() );
        }
        return b.toString();
    }

    @Override
    public boolean isCacheable()
    {
        // the os is not going to change between projects in the same build.
        return true;
    }

    @Override
    public boolean isResultValid( EnforcerRule theCachedRule )
    {
        // i will always return the hash of the parameters as my id. If my parameters are the same, this
        // rule must always have the same result.
        return true;
    }
}
