/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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.
 */

package org.apache.xmlbeans.impl.marshal;

import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
import org.apache.xmlbeans.impl.binding.bts.BindingType;
import org.apache.xmlbeans.impl.binding.bts.BindingTypeName;
import org.apache.xmlbeans.impl.binding.bts.JaxrpcEnumType;
import org.apache.xmlbeans.impl.common.InvalidLexicalValueException;
import org.apache.xmlbeans.impl.marshal.util.ReflectionUtils;

import java.lang.reflect.Method;

final class JaxrpcEnumRuntimeBindingType
    extends RuntimeBindingType
{
    private final JaxrpcEnumType jaxrpcEnumType;
    private ItemInfo itemInfo;

    JaxrpcEnumRuntimeBindingType(JaxrpcEnumType type)
        throws XmlException
    {
        super(type);
        jaxrpcEnumType = type;
    }

    void accept(RuntimeTypeVisitor visitor)
        throws XmlException
    {
        visitor.visit(this);
    }

    public void initialize(RuntimeBindingTypeTable typeTable,
                           BindingLoader bindingLoader
                           )
        throws XmlException
    {
        itemInfo = new ItemInfo(jaxrpcEnumType, getJavaType(), typeTable,
                                bindingLoader);
    }

    boolean hasElementChildren()
    {
        return false;
    }

    CharSequence print(Object value,
                       MarshalResult result)
        throws XmlException
    {
        if (itemInfo.hasToXmlMethod()) {
            return (String)ReflectionUtils.invokeMethod(value,
                                                        itemInfo.getToXmlMethod());
        } else {
            final Object simple_content = extractValue(value);
            return itemInfo.getItemMarshaller().print(simple_content, result);
        }
    }

    private Object extractValue(Object value)
        throws XmlException
    {
        return ReflectionUtils.invokeMethod(value,
                                            itemInfo.getGetValueMethod());
    }

    TypeUnmarshaller getItemUnmarshaller()
    {
        return itemInfo.getItemUnmarshaller();
    }

    Object fromValue(Object itemValue, UnmarshalResult context)
        throws XmlException
    {
        assert itemValue != null;
        assert context != null;
        try {
            return ReflectionUtils.invokeMethod(null, itemInfo.getFromValueMethod(),
                                                new Object[]{itemValue});
        }
        catch (XmlException iae) {
            throw new InvalidLexicalValueException(iae, context.getLocation());
        }
    }


    private static final class ItemInfo
    {
        private final RuntimeBindingType itemType;
        private final Method getValueMethod;
        private final Method fromValueMethod;
        private final Method toXmlMethod;

        ItemInfo(JaxrpcEnumType jaxrpcEnumType,
                 Class enum_java_class,
                 RuntimeBindingTypeTable typeTable,
                 BindingLoader loader)
            throws XmlException
        {
            final BindingTypeName base_name = jaxrpcEnumType.getBaseTypeName();
            if (base_name == null) {
                throw new XmlException("null base type for " + jaxrpcEnumType);
            }
            final BindingType item_type = loader.getBindingType(base_name);
            if (item_type == null) {
                final String msg = "unable to load type " + base_name +
                    " for " + jaxrpcEnumType;
                throw new XmlException(msg);
            }

            itemType =
                typeTable.createRuntimeType(item_type, loader);

            fromValueMethod =
                ReflectionUtils.getMethodOnClass(jaxrpcEnumType.getFromValueMethod(),
                                                 enum_java_class);
            if (!ReflectionUtils.isMethodStatic(fromValueMethod)) {
                String e = "fromValue method must be static.  invalid " +
                    "method: " + fromValueMethod + " in type " + jaxrpcEnumType;
                throw new XmlException(e);
            }

            getValueMethod =
                ReflectionUtils.getMethodOnClass(jaxrpcEnumType.getGetValueMethod(),
                                                 enum_java_class);
            toXmlMethod =
                ReflectionUtils.getMethodOnClass(jaxrpcEnumType.getToXMLMethod(),
                                                 enum_java_class);

            //final sanity checks
            TypeMarshaller itemMarshaller = itemType.getMarshaller();
            if (itemMarshaller == null) {
                String m = "unable to locate marshaller for " + item_type;
                throw new XmlException(m);
            }

            final Class[] parms = fromValueMethod.getParameterTypes();
            if (parms.length != 1) {
                throw new XmlException("invalid fromValue method, must have" +
                                       " one parameter: " + fromValueMethod +
                                       " for type " + jaxrpcEnumType);
            }
            if (!parms[0].isAssignableFrom(itemType.getJavaType())) {
                String m =
                    "invalid fromValue method:" + fromValueMethod +
                    " --  type mismatch between: " + parms[0] +
                    " and " + itemType.getJavaType() +
                    " for type " + jaxrpcEnumType;
                throw new XmlException(m);
            }
        }

        TypeMarshaller getItemMarshaller()
        {
            return itemType.getMarshaller();
        }

        TypeUnmarshaller getItemUnmarshaller()
        {
            return itemType.getUnmarshaller();
        }

        Method getGetValueMethod()
        {
            return getValueMethod;
        }

        Method getFromValueMethod()
        {
            return fromValueMethod;
        }

        Method getToXmlMethod()
        {
            return toXmlMethod;
        }

        boolean hasToXmlMethod()
        {
            return toXmlMethod != null;
        }

    }

}
