/*   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.
 */
/**
 * Author: Cezar Andrei ( cezar.andrei at bea.com )
 * Date: Mar 25, 2004
 */
package org.apache.xmlbeans.impl.config;

import org.apache.xml.xmlbeans.x2004.x02.xbean.config.Extensionconfig;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlBeans;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class InterfaceExtension
{
    private NameSet _xbeanSet;
    private Class _interface;
    private Class _delegateToClass;
    private String _delegateToClassName;
    private Method[] _interfaceMethods;
    private Method[] _delegateToMethods;

    static InterfaceExtension newInstance(NameSet xbeanSet, Extensionconfig.Interface intfXO)
    {
        InterfaceExtension result = new InterfaceExtension();

        result._xbeanSet = xbeanSet;
        result._interface = validateInterface(intfXO.getName(), intfXO);

        if (result._interface == null)
        {
            SchemaConfig.error("Interface '" + intfXO.getStaticHandler() + "' not found.", intfXO);
            return null;
        }

        result._delegateToClassName = intfXO.getStaticHandler();
        result._delegateToClass = validateClass(result._delegateToClassName, intfXO);

        if ( result._delegateToClass==null ) // no HandlerClass
        {
            SchemaConfig.warning("Handler class '" + intfXO.getStaticHandler() + "' not found on classpath, skip validation.", intfXO);
            return result;
        }

        if (!result.validateMethods(intfXO))
            return null;

        return result;
    }

    private static Class validateInterface(String intfStr, XmlObject loc)
    {
        return validateJava(intfStr, true, loc);
    }

    static Class validateClass(String clsStr, XmlObject loc)
    {
        return validateJava(clsStr, false, loc);
    }

    static Class validateJava(String clsStr, boolean isInterface, XmlObject loc)
    {
        final String ent = isInterface ? "Interface" : "Class";
        try
        {
            Class cls = Class.forName(clsStr);
            if ( (isInterface && !cls.isInterface()) ||
                    (!isInterface && cls.isInterface()))
            {
                SchemaConfig.error("'" + clsStr + "' must be " +
                    (isInterface ? "an interface" : "a class") + ".", loc);
            }

            if (!Modifier.isPublic(cls.getModifiers()))
            {
                SchemaConfig.error(ent + " '" + clsStr + "' is not public.", loc);
            }

            return cls;
        }
        catch (ClassNotFoundException e)
        {
            SchemaConfig.error(ent + " '" + clsStr + "' not found.", loc);
            return null;
        }
    }

    private boolean validateMethods(XmlObject loc)
    {
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue(_delegateToClass != null, "Delegate to class handler expected.");
        boolean valid = true;

        _interfaceMethods = _interface.getMethods();
        _delegateToMethods = new Method[_interfaceMethods.length];

        for (int i = 0; i < _interfaceMethods.length; i++)
        {
            valid &= validateMethod(i, _interfaceMethods[i], loc);
        }

        return valid;
    }

    private boolean validateMethod(int index, Method method, XmlObject loc)
    {
        String methodName = method.getName();
        Class[] paramTypes = method.getParameterTypes();
        Class returnType = method.getReturnType();

        Class[] delegateParams = new Class[paramTypes.length+1];
        delegateParams[0] = XmlObject.class;
        for (int i = 1; i < delegateParams.length; i++)
        {
            delegateParams[i] = paramTypes[i-1];
        }

        Method handlerMethod = null;
        try
        {
            handlerMethod = _delegateToClass.getMethod(methodName, delegateParams);

            // check for throws exceptions
            Class[] intfExceptions = method.getExceptionTypes();
            Class[] delegateExceptions = handlerMethod.getExceptionTypes();
            if ( delegateExceptions.length!=intfExceptions.length )
            {
                SchemaConfig.error("Handler method '" + _delegateToClass.getName() + "." + methodName + "(" + listTypes(delegateParams) +
                    ")' must declare the same exceptions as the interface method '" + _interface.getName() + "." + methodName + "(" + listTypes(paramTypes), loc);
                return false;
            }

            for (int i = 0; i < delegateExceptions.length; i++)
            {
                if ( delegateExceptions[i]!=intfExceptions[i] )
                {
                    SchemaConfig.error("Handler method '" + _delegateToClass.getName() + "." + methodName + "(" + listTypes(delegateParams) +
                        ")' must declare the same exceptions as the interface method '" + _interface.getName() + "." + methodName + "(" + listTypes(paramTypes), loc);
                    return false;
                }
            }
        }
        catch (NoSuchMethodException e)
        {
            SchemaConfig.error("Handler class '" + _delegateToClass.getName() + "' does not contain method " + methodName + "(" + listTypes(delegateParams) + ")", loc);
            return false;
        }
        catch (SecurityException e)
        {
            SchemaConfig.error("Security violation for class '" + _interface.getName() + "' accesing method " + methodName + "(" + listTypes(delegateParams) + ")", loc);
            return false;
        }

        if (!Modifier.isPublic(handlerMethod.getModifiers()) || !Modifier.isStatic(handlerMethod.getModifiers()))
        {
            SchemaConfig.error("Method '" + _delegateToClass.getName() + "." + methodName + "(" + listTypes(delegateParams) + ")' must be declared public and static.", loc);
            return false;
        }

        if (!returnType.equals(handlerMethod.getReturnType()))
        {
            SchemaConfig.error("Return type for method '" + handlerMethod.getReturnType() + " " + _delegateToClass.getName() +
                    "." + methodName + "(" + listTypes(delegateParams) + ")' does not match the return type of the interface method :'" + returnType + "'.", loc);
            return false;
        }

        _delegateToMethods[index] = method;

        return true;
    }

    private static String listTypes(Class[] types)
    {
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < types.length; i++)
        {
            Class type = types[i];
            if (i>0)
                result.append(", ");
            result.append(emitType(type));
        }
        return result.toString();
    }

    public static String emitType(Class cls)
    {
        if (cls.isArray())
            return emitType(cls.getComponentType()) + "[]";
        else
            return cls.getName().replace('$', '.');
    }

    /* public getters */
    public boolean contains(String fullJavaName)
    {
        return _xbeanSet.contains(fullJavaName);
    }

    public String getInterfaceName()
    {
        return _interface.getName();
    }

    public String getInterfaceNameForJavaSource()
    {
        return emitType(_interface);
    }

    // used only for validation
    public String getHandlerNameForJavaSource()
    {
        if (_delegateToClass==null)
            return null;

        return emitType(_delegateToClass);
    }

    public int getInterfaceMethodCount()
    {
        return _interfaceMethods.length;
    }

    public String getInterfaceMethodName(int methodIndex)
    {
        return _interfaceMethods[methodIndex].getName();
    }

    public Method getInterfaceMethod(int methodIndex)
    {
        return _interfaceMethods[methodIndex];
    }

    public String getInterfaceMethodDecl(int methodIndex)
    {
        StringBuffer sb = new StringBuffer();
        Method m = _interfaceMethods[methodIndex];
        Class[] paramTypes = m.getParameterTypes();

        for (int i = 0; i < paramTypes.length; i++)
        {
            Class paramType = paramTypes[i];
            sb.append( i==0 ? "" : ", " );
            sb.append( emitType(paramType) + " p" + i);
        }

        StringBuffer exceptions = new StringBuffer();
        Class[] excClasses = m.getExceptionTypes();

        for (int i=0; i<excClasses.length; i++)
            exceptions.append((i==0 ? " throws " : ", ") + emitType(excClasses[i]));

        return "public " + emitType(m.getReturnType()) + " " + m.getName() + "(" + sb.toString() + ")" + exceptions.toString();
    }

    public String getInterfaceMethodImpl(int methodIndex)
    {
	// use the methods from the interface for gen the call to the handler
        StringBuffer sb = new StringBuffer();

        if (!void.class.equals(_interfaceMethods[methodIndex].getReturnType()))
            sb.append("return ");

        sb.append(_delegateToClassName + "." + _delegateToMethods[methodIndex].getName() + "(this");

        int paramCount = _interfaceMethods[methodIndex].getParameterTypes().length;
        for (int i=0; i<paramCount; i++)
        {
            sb.append(", p" + i);
        }

        sb.append(");");
        return sb.toString();
    }
}
