//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.websocket.common.events.annotated;

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

import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
import org.eclipse.jetty.websocket.common.events.ParamList;

/**
 * Basic scanner for Annotated Methods
 */
public abstract class AbstractMethodAnnotationScanner<T>
{
    protected void assertIsPublicNonStatic(Method method)
    {
        int mods = method.getModifiers();
        if (!Modifier.isPublic(mods))
        {
            StringBuilder err = new StringBuilder();
            err.append("Invalid declaration of ");
            err.append(method);
            err.append(System.lineSeparator());

            err.append("Method modifier must be public");

            throw new InvalidWebSocketException(err.toString());
        }

        if (Modifier.isStatic(mods))
        {
            StringBuilder err = new StringBuilder();
            err.append("Invalid declaration of ");
            err.append(method);
            err.append(System.lineSeparator());

            err.append("Method modifier may not be static");

            throw new InvalidWebSocketException(err.toString());
        }
    }

    protected void assertIsReturn(Method method, Class<?> type)
    {
        if (!type.equals(method.getReturnType()))
        {
            StringBuilder err = new StringBuilder();
            err.append("Invalid declaration of ");
            err.append(method);
            err.append(System.lineSeparator());

            err.append("Return type must be ").append(type);

            throw new InvalidWebSocketException(err.toString());
        }
    }

    protected void assertIsVoidReturn(Method method)
    {
        assertIsReturn(method,Void.TYPE);
    }

    protected void assertUnset(CallableMethod callable, Class<? extends Annotation> annoClass, Method method)
    {
        if (callable != null)
        {
            // Attempt to add duplicate frame type (a no-no)
            StringBuilder err = new StringBuilder();
            err.append("Duplicate @").append(annoClass.getSimpleName()).append(" declaration on ");
            err.append(method);
            err.append(System.lineSeparator());

            err.append("@").append(annoClass.getSimpleName()).append(" previously declared at ");
            err.append(callable.getMethod());

            throw new InvalidWebSocketException(err.toString());
        }
    }

    protected void assertValidSignature(Method method, Class<? extends Annotation> annoClass, ParamList validParams)
    {
        assertIsPublicNonStatic(method);
        assertIsReturn(method,Void.TYPE);

        boolean valid = false;

        // validate parameters
        Class<?> actual[] = method.getParameterTypes();
        for (Class<?>[] params : validParams)
        {
            if (isSameParameters(actual,params))
            {
                valid = true;
                break;
            }
        }

        if (!valid)
        {
            throw InvalidSignatureException.build(method,annoClass,validParams);
        }
    }

    public boolean isAnnotation(Annotation annotation, Class<? extends Annotation> annotationClass)
    {
        return annotation.annotationType().equals(annotationClass);
    }

    public boolean isSameParameters(Class<?>[] actual, Class<?>[] params)
    {
        if (actual.length != params.length)
        {
            // skip
            return false;
        }

        int len = params.length;
        for (int i = 0; i < len; i++)
        {
            if (!actual[i].equals(params[i]))
            {
                return false; // not valid
            }
        }

        return true;
    }

    protected boolean isSignatureMatch(Method method, ParamList validParams)
    {
        assertIsPublicNonStatic(method);
        assertIsReturn(method,Void.TYPE);

        // validate parameters
        Class<?> actual[] = method.getParameterTypes();
        for (Class<?>[] params : validParams)
        {
            if (isSameParameters(actual,params))
            {
                return true;
            }
        }

        return false;
    }

    protected boolean isTypeAnnotated(Class<?> pojo, Class<? extends Annotation> expectedAnnotation)
    {
        return pojo.getAnnotation(expectedAnnotation) != null;
    }

    public abstract void onMethodAnnotation(T metadata, Class<?> pojo, Method method, Annotation annotation);

    public void scanMethodAnnotations(T metadata, Class<?> pojo)
    {
        Class<?> clazz = pojo;

        while ((clazz != null) && Object.class.isAssignableFrom(clazz))
        {
            for (Method method : clazz.getDeclaredMethods())
            {
                Annotation annotations[] = method.getAnnotations();
                if ((annotations == null) || (annotations.length <= 0))
                {
                    continue; // skip
                }
                for (Annotation annotation : annotations)
                {
                    onMethodAnnotation(metadata,clazz,method,annotation);
                }
            }

            clazz = clazz.getSuperclass();
        }
    }
}
