/*
 *   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.
 *
 */
package org.apache.directory.fortress.rest;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.common.util.ClassHelper;
import org.apache.cxf.interceptor.security.SimpleAuthorizingInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Security Utility for Fortress Rest Server.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class FortressInterceptor extends SimpleAuthorizingInterceptor
{
    /** A logger for this class */
    private static final Logger LOG = LoggerFactory.getLogger( FortressInterceptor.class.getName() );

    //private static final String DEFAULT_ANNOTATION_CLASS_NAME = "javax.annotation.security.RolesAllowed";
    private static final String DEFAULT_ANNOTATION_CLASS_NAME = "jakarta.annotation.security.RolesAllowed";

    /** The list of methods we want to skip */
    private static final Set<String> SKIP_METHODS;

    static
    {
        SKIP_METHODS = new HashSet<String>();
        SKIP_METHODS.addAll( Arrays.asList(
            new String[]{ "wait", "notify", "notifyAll",
                "equals", "toString", "hashCode" } ) );
    }

    private String annotationClassName = DEFAULT_ANNOTATION_CLASS_NAME;

    /**
     *
     * @param name The annotation class name
     */
    public void setAnnotationClassName( String name )
    {
        try
        {
            LOG.info( "FortressInterceptor.setAnnotationClassName:" + name );
            ClassLoaderUtils.loadClass( name, FortressInterceptor.class );
            annotationClassName = name;
        }
        catch ( ClassNotFoundException ex )
        {
            LOG.info( "FortressInterceptor.setAnnotationClassName caught ClassNotFoundException-" + ex );
        }
    }
    

    /**
     *
     * @param object The Object to secure
     */
    public void setSecuredObject( Object object )
    {
        LOG.info( "FortressInterceptor.setSecuredObject:" + object );
        Class<?> cls = ClassHelper.getRealClass( object );
        Map<String, String> rolesMap = new HashMap<String, String>();
        findRoles( cls, rolesMap );
        
        if ( rolesMap.isEmpty() )
        {
            LOG.info( "FortressInterceptor.setSecuredObject The roles map is empty, the service object is not protected" );
        }
        else if ( LOG.isDebugEnabled() )
        {
            for ( Map.Entry<String, String> entry : rolesMap.entrySet() )
            {
                LOG.debug( "FortressInterceptor.setSecuredObject Method: " + entry.getKey() + ", roles: " + entry.getValue() );
            }
        }
        
        super.setMethodRolesMap( rolesMap );
    }
    

    /**
     * Find the list of 
     * @param cls The class for which we want to find roles
     * @param rolesMap The Map containing the roles
     */
    protected void findRoles( Class<?> cls, Map<String, String> rolesMap )
    {
        LOG.info( "FortressInterceptor.findRoles:" + rolesMap );
        
        if ( ( cls == null ) || ( cls == Object.class ) )
        {
            return;
        }
        
        String classRolesAllowed = getRoles( cls.getAnnotations(), annotationClassName );
        
        // Process all the methods for the given class itself
        for ( Method m : cls.getMethods() )
        {
            if ( SKIP_METHODS.contains( m.getName() ) )
            {
                continue;
            }
            
            String methodRolesAllowed = getRoles( m.getAnnotations(), annotationClassName );
            
            if ( methodRolesAllowed != null )
            {
                rolesMap.put( m.getName(), methodRolesAllowed );
            }
            else if ( classRolesAllowed != null )
            {
                rolesMap.put( m.getName(), classRolesAllowed );
            }
        }
        
        // We have found roles in the current class, get out
        if ( !rolesMap.isEmpty() )
        {
            return;
        }

        // Chekc the super class now
        findRoles( cls.getSuperclass(), rolesMap );

        // Get out if we have some roles
        if ( !rolesMap.isEmpty() )
        {
            return;
        }

        // Still nothing ? let's check the interfaces
        for ( Class<?> interfaceCls : cls.getInterfaces() )
        {
            findRoles( interfaceCls, rolesMap );
        }
    }

    
    /**
     *
     * @param anns
     * @param annName
     * @return String roles
     */
    private String getRoles( Annotation[] anns, String annName )
    {
        LOG.debug( "FortressInterceptor.getRoles:" + annName );
        
        for ( Annotation ann : anns )
        {
            if ( ann.annotationType().getName().equals( annName ) )
            {
                try
                {
                    Method valueMethod = ann.annotationType().getMethod( "value", new Class[]{} );
                    String[] roles = (String[]) valueMethod.invoke( ann, new Object[]{} );
                    StringBuilder sb = new StringBuilder();
                    boolean isFirst = false;
                    
                    for ( String role : roles )
                    {
                        if ( isFirst )
                        {
                            isFirst = false;
                        }
                        else
                        {
                            sb.append( " " );
                        }
                        
                        sb.append( role );
                    }
                    
                    return sb.toString();
                }
                catch ( NoSuchMethodException ex )
                {
                    LOG.info( "FortressInterceptor.getRoles annName=" + annName + ", caught NoSuchMethodException=" + ex );
                }
                catch ( IllegalAccessException ex )
                {
                    LOG.info( "FortressInterceptor.getRoles annName=" + annName + ", caught IllegalAccessException=" + ex );
                }
                catch ( InvocationTargetException ex )
                {
                    LOG.info( "FortressInterceptor.getRoles annName=" + annName + ", caught InvocationTargetException=" + ex );
                }
                break;
            }
        }
        
        return null;
    }
}

