package org.apache.commons.digester3.binder;

/*
 * 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 static java.lang.String.format;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.digester3.ObjectCreateRule;

/**
 * Builder chained when invoking {@link LinkedRuleBuilder#createObject()}.
 *
 * @since 3.0
 */
public final class ObjectCreateBuilder
    extends AbstractBackToLinkedRuleBuilder<ObjectCreateRule>
{
    private static final Map<String, Class<?>> PRIMITIVE_TYPES;
    static
    {
        HashMap<String, Class<?>> primitiveTypes = new HashMap<String, Class<?>>();
        primitiveTypes.put("boolean", boolean.class);
        primitiveTypes.put("byte", byte.class);
        primitiveTypes.put("short", short.class);
        primitiveTypes.put("int", int.class);
        primitiveTypes.put("char", char.class);
        primitiveTypes.put("long", long.class);
        primitiveTypes.put("float", float.class);
        primitiveTypes.put("double", double.class);
        PRIMITIVE_TYPES = Collections.unmodifiableMap(primitiveTypes);
    }

    private final ClassLoader classLoader;

    private Class<?> type;

    private String attributeName;

    /**
     * The constructor argument types
     *
     * @since 3.2
     */
    private Class<?>[] constructorArgumentsType;

    /**
     * Default constructor arguments.
     *
     * @since 3.2
     */
    private Object[] defaultConstructorArguments;

    ObjectCreateBuilder( String keyPattern, String namespaceURI, RulesBinder mainBinder, LinkedRuleBuilder mainBuilder,
                         ClassLoader classLoader )
    {
        super( keyPattern, namespaceURI, mainBinder, mainBuilder );
        this.classLoader = classLoader;
    }

    /**
     * Construct an object with the specified class name.
     *
     * @param className Java class name of the object to be created
     * @return this builder instance
     */
    public ObjectCreateBuilder ofType( String className )
    {
        if ( className == null )
        {
            reportError( "createObject().ofType( String )", "NULL Java type not allowed" );
            return this;
        }

        try
        {
            return ofType( this.classLoader.loadClass( className ) );
        }
        catch ( ClassNotFoundException e )
        {
            reportError( "createObject().ofType( String )", String.format( "class '%s' cannot be load", className ) );
            return this;
        }
    }

    /**
     * Construct an object with the specified class.
     *
     * @param <T> any java type
     * @param type Java class of the object to be created
     * @return this builder instance
     */
    public <T> ObjectCreateBuilder ofType( Class<T> type )
    {
        if ( type == null )
        {
            reportError( "createObject().ofType( Class<?> )", "NULL Java type not allowed" );
            return this;
        }

        this.type = type;

        return this;
    }

    /**
     * Allows specify the attribute containing an override class name if it is present.
     *
     * @param attributeName The attribute containing an override class name if it is present
     * @return this builder instance
     */
    public ObjectCreateBuilder ofTypeSpecifiedByAttribute( /* @Nullable */String attributeName )
    {
        this.attributeName = attributeName;
        return this;
    }

    /**
     *
     * @return
     * @since 3.2
     */
    public ObjectCreateBuilder usingConstructor( String...paramTypeNames )
    {
        if ( paramTypeNames == null )
        {
            reportError( "createObject().usingConstructor( String[] )", "NULL parametersTypes not allowed" );
            return this;
        }

        Class<?>[] paramTypes = new Class<?>[paramTypeNames.length];
        for ( int i = 0; i < paramTypeNames.length; i++ )
        {
            if ( PRIMITIVE_TYPES.containsKey( paramTypeNames[i] ) )
            {
                paramTypes[i] = PRIMITIVE_TYPES.get( paramTypeNames[i] );
                continue;
            }
            try
            {
                paramTypes[i] = classLoader.loadClass( paramTypeNames[i] );
            }
            catch ( ClassNotFoundException e )
            {
                this.reportError( format( "createObject().usingConstructor( %s )",
                                          Arrays.toString( paramTypeNames ) ),
                                  format( "class '%s' cannot be loaded", paramTypeNames[i] ) );
            }
        }

        return usingConstructor( paramTypes );
    }

    /**
     *
     * @return
     * @since 3.2
     */
    public ObjectCreateBuilder usingConstructor( Class<?>... constructorArgumentTypes )
    {
        if ( constructorArgumentTypes == null )
        {
            reportError( "createObject().usingConstructor( Class<?>[] )", "NULL constructorArgumentTypes not allowed" );
            return this;
        }

        this.constructorArgumentsType = constructorArgumentTypes;

        return this;
    }

    public ObjectCreateBuilder usingDefaultConstructorArguments( Object... defaultConstructorArguments)
    {
        if ( defaultConstructorArguments == null )
        {
            reportError( "createObject().usingDefaultConstructorArguments( Object[] )", "NULL defaultConstructorArguments not allowed" );
            return this;
        }

        this.defaultConstructorArguments = defaultConstructorArguments;

        return this;

    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected ObjectCreateRule createRule()
    {
        ObjectCreateRule objectCreateRule = new ObjectCreateRule( attributeName, type );

        if ( constructorArgumentsType != null )
        {
            objectCreateRule.setConstructorArgumentTypes( constructorArgumentsType );
        }
        if ( defaultConstructorArguments != null )
        {
            objectCreateRule.setDefaultConstructorArguments( defaultConstructorArguments );
        }

        return objectCreateRule;
    }

}
