package org.apache.maven.scm;

/*
 * 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.io.File;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
 * @author Olivier Lamy
 * @version $Id$
 */
public class CommandParameters
    implements Serializable
{
    private static final long serialVersionUID = -7346070735958137283L;

    private Map<String, Object> parameters = new HashMap<String, Object>();

    // ----------------------------------------------------------------------
    // String
    // ----------------------------------------------------------------------

    /**
     * Return the parameter value as String.
     *
     * @param parameter The parameter
     * @return The parameter value as a String
     * @throws ScmException if the parameter doesn't exist
     */
    public String getString( CommandParameter parameter )
        throws ScmException
    {
        Object object = getObject( String.class, parameter );

        if ( object == null )
        {
            throw new ScmException( "Missing parameter: '" + parameter.getName() + "'." );
        }

        return object.toString();
    }

    /**
     * Return the parameter value or the default value if it doesn't exist.
     *
     * @param parameter    The parameter
     * @param defaultValue The default value
     * @return The parameter value as a String
     * @throws ScmException if the value is in the wrong type
     */
    public String getString( CommandParameter parameter, String defaultValue )
        throws ScmException
    {
        Object object = getObject( String.class, parameter, null );

        if ( object == null )
        {
            return defaultValue;
        }

        return object.toString();
    }

    /**
     * Set a parameter value.
     *
     * @param parameter The parameter name
     * @param value     The value of the parameter
     * @throws ScmException if the parameter already exist
     */
    public void setString( CommandParameter parameter, String value )
        throws ScmException
    {
        setObject( parameter, value );
    }

    // ----------------------------------------------------------------------
    // Int
    // ----------------------------------------------------------------------

    /**
     * Return the parameter value as int.
     *
     * @param parameter The parameter
     * @return The parameter value as a String
     * @throws ScmException if the parameter doesn't exist
     */
    public int getInt( CommandParameter parameter )
        throws ScmException
    {
        return ( (Integer) getObject( Integer.class, parameter ) ).intValue();
    }

    /**
     * Return the parameter value as int or the default value if it doesn't exist.
     *
     * @param parameter    The parameter
     * @param defaultValue The defaultValue
     * @return The parameter value as a int
     * @throws ScmException if the value is in the wrong type
     */
    public int getInt( CommandParameter parameter, int defaultValue )
        throws ScmException
    {
        Integer value = ( (Integer) getObject( Integer.class, parameter, null ) );

        if ( value == null )
        {
            return defaultValue;
        }

        return value.intValue();
    }

    /**
     * Set a parameter value.
     *
     * @param parameter The parameter name
     * @param value     The value of the parameter
     * @throws ScmException if the parameter already exist
     */
    public void setInt( CommandParameter parameter, int value )
        throws ScmException
    {
        setObject( parameter, Integer.valueOf( value ) );
    }

    // ----------------------------------------------------------------------
    // Date
    // ----------------------------------------------------------------------

    /**
     * Return the parameter value as Date.
     *
     * @param parameter The parameter
     * @return The parameter value as a Date
     * @throws ScmException if the parameter doesn't exist
     */
    public Date getDate( CommandParameter parameter )
        throws ScmException
    {
        return (Date) getObject( Date.class, parameter );
    }

    /**
     * Return the parameter value as String or the default value if it doesn't exist.
     *
     * @param parameter    The parameter
     * @param defaultValue The defaultValue
     * @return The parameter value as a Date
     * @throws ScmException if the value is in the wrong type
     */
    public Date getDate( CommandParameter parameter, Date defaultValue )
        throws ScmException
    {
        return (Date) getObject( Date.class, parameter, defaultValue );
    }

    /**
     * Set a parameter value.
     *
     * @param parameter The parameter name
     * @param date      The value of the parameter
     * @throws ScmException if the parameter already exist
     */
    public void setDate( CommandParameter parameter, Date date )
        throws ScmException
    {
        setObject( parameter, date );
    }

    // ----------------------------------------------------------------------
    // Boolean
    // ----------------------------------------------------------------------

    /**
     * Return the parameter value as boolean.
     *
     * @param parameter The parameter
     * @return The parameter value as a boolean
     * @throws ScmException if the parameter doesn't exist
     */
    public boolean getBoolean( CommandParameter parameter )
        throws ScmException
    {
        return Boolean.valueOf( getString( parameter ) ).booleanValue();
    }

    /**
     * Return the parameter value as boolean.
     *
     * @since 1.7
     * @param parameter    The parameter
     * @param defaultValue default value if parameter not exists
     * @return The parameter value as a boolean
     */
    public boolean getBoolean( CommandParameter parameter, boolean defaultValue )
        throws ScmException
    {
        return Boolean.valueOf( getString( parameter, Boolean.toString( defaultValue ) ) ).booleanValue();
    }

    // ----------------------------------------------------------------------
    // ScmVersion
    // ----------------------------------------------------------------------

    /**
     * Return the parameter value as ScmVersion.
     *
     * @param parameter The parameter
     * @return The parameter value as a ScmVersion
     * @throws ScmException if the parameter doesn't exist
     */
    public ScmVersion getScmVersion( CommandParameter parameter )
        throws ScmException
    {
        return (ScmVersion) getObject( ScmVersion.class, parameter );
    }

    /**
     * Return the parameter value as ScmVersion or the default value.
     *
     * @param parameter    The parameter
     * @param defaultValue The default value
     * @return The parameter value as a ScmVersion
     * @throws ScmException if the parameter doesn't exist
     */
    public ScmVersion getScmVersion( CommandParameter parameter, ScmVersion defaultValue )
        throws ScmException
    {
        return (ScmVersion) getObject( ScmVersion.class, parameter, defaultValue );
    }

    /**
     * Set a parameter value.
     *
     * @param parameter  The parameter name
     * @param scmVersion The tbranch/tag/revision
     * @throws ScmException if the parameter already exist
     */
    public void setScmVersion( CommandParameter parameter, ScmVersion scmVersion )
        throws ScmException
    {
        setObject( parameter, scmVersion );
    }

    // ----------------------------------------------------------------------
    // File[]
    // ----------------------------------------------------------------------

    /**
     * @param parameter not null
     * @return an array of files
     * @throws ScmException if any
     */
    public File[] getFileArray( CommandParameter parameter )
        throws ScmException
    {
        return (File[]) getObject( File[].class, parameter );
    }

    /**
     * @param parameter    not null
     * @param defaultValue could be null
     * @return an array of files
     * @throws ScmException if any
     */
    public File[] getFileArray( CommandParameter parameter, File[] defaultValue )
        throws ScmException
    {
        return (File[]) getObject( File[].class, parameter, defaultValue );
    }


    public ScmTagParameters getScmTagParameters( CommandParameter parameter )
        throws ScmException
    {
        return (ScmTagParameters) getObject( ScmTagParameters.class, parameter, new ScmTagParameters() );
    }

    public void setScmTagParameters( CommandParameter parameter, ScmTagParameters scmTagParameters )
        throws ScmException
    {
        setObject( parameter, scmTagParameters );
    }

    public void setScmBranchParameters( CommandParameter parameter, ScmBranchParameters scmBranchParameters )
        throws ScmException
    {
        setObject( parameter, scmBranchParameters );
    }

    public ScmBranchParameters getScmBranchParameters( CommandParameter parameter )
        throws ScmException
    {
        return (ScmBranchParameters) getObject( ScmBranchParameters.class, parameter, new ScmBranchParameters() );
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    /**
     * Return the value object.
     *
     * @param clazz     The type of the parameter value
     * @param parameter The parameter
     * @return The parameter value
     * @throws ScmException if the parameter doesn't exist
     */
    private Object getObject( Class<?> clazz, CommandParameter parameter )
        throws ScmException
    {
        Object object = getObject( clazz, parameter, null );

        if ( object == null )
        {
            throw new ScmException( "Missing parameter: '" + parameter.getName() + "'." );
        }

        return object;
    }

    /**
     * Return the value object or the default value if it doesn't exist.
     *
     * @param clazz        The type of the parameter value
     * @param parameter    The parameter
     * @param defaultValue The defaultValue
     * @return The parameter value
     * @throws ScmException if the defaultValue is in the wrong type
     */
    private Object getObject( Class<?> clazz, CommandParameter parameter, Object defaultValue )
        throws ScmException
    {
        Object object = parameters.get( parameter.getName() );

        if ( object == null )
        {
            return defaultValue;
        }

        if ( clazz != null && !clazz.isAssignableFrom( object.getClass() ) )
        {
            throw new ScmException(
                "Wrong parameter type for '" + parameter.getName() + ". " + "Expected: " + clazz.getName() + ", got: "
                    + object.getClass().getName() );
        }

        return object;
    }

    /**
     * Set the parameter value.
     *
     * @param parameter The parameter
     * @param value     The parameter value
     * @throws ScmException if the parameter already exist
     */
    private void setObject( CommandParameter parameter, Object value )
        throws ScmException
    {
        Object object = getObject( null, parameter, null );

        if ( object != null )
        {
            throw new ScmException( "The parameter is already set: " + parameter.getName() );
        }

        parameters.put( parameter.getName(), value );
    }
}
