/*
    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.wiki.ui.admin;

import org.apache.log4j.Logger;
import org.apache.wiki.api.Release;
import org.apache.wiki.api.core.Engine;
import org.apache.wiki.event.WikiEngineEvent;
import org.apache.wiki.event.WikiEvent;
import org.apache.wiki.event.WikiEventListener;
import org.apache.wiki.modules.ModuleManager;
import org.apache.wiki.modules.WikiModuleInfo;
import org.apache.wiki.ui.admin.beans.CoreBean;
import org.apache.wiki.ui.admin.beans.FilterBean;
import org.apache.wiki.ui.admin.beans.PluginBean;
import org.apache.wiki.ui.admin.beans.SearchManagerBean;
import org.apache.wiki.ui.admin.beans.UserBean;

import javax.management.DynamicMBean;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


/**
 *  Provides a manager class for all AdminBeans within JSPWiki.  This class also manages registration for any
 *  AdminBean which is also a JMX bean.
 *
 *  @since  2.5.52
 */
public class DefaultAdminBeanManager implements WikiEventListener, AdminBeanManager {

    private final Engine m_engine;
    private ArrayList< AdminBean > m_allBeans;
    private final MBeanServer m_mbeanServer;

    private static final Logger log = Logger.getLogger( DefaultAdminBeanManager.class );

    public DefaultAdminBeanManager( final Engine engine ) {
        log.info("Using JDK 1.5 Platform MBeanServer");
        m_mbeanServer = MBeanServerFactory15.getServer();

        m_engine = engine;

        if( m_mbeanServer != null ) {
            log.info( m_mbeanServer.getClass().getName() );
            log.info( m_mbeanServer.getDefaultDomain() );
        }

        m_engine.addWikiEventListener( this );
        initialize();
    }

    /** {@inheritDoc} */
    @Override
	public void initialize() {
        reload();
    }

    private String getJMXTitleString( final int title ) {
        switch( title ) {
            case AdminBean.CORE:
                return "Core";

            case AdminBean.EDITOR:
                return "Editors";

            case AdminBean.UNKNOWN:
            default:
                return "Unknown";
        }
    }


    /**
     *  Register an AdminBean.  If the AdminBean is also a JMX MBean, it also gets registered to the MBeanServer we've found.
     *
     *  @param ab AdminBean to register.
     */
    private void registerAdminBean( final AdminBean ab ) {
        try {
            if( ab instanceof DynamicMBean && m_mbeanServer != null ) {
                final ObjectName name = getObjectName( ab );
                if( !m_mbeanServer.isRegistered( name ) ) {
                    m_mbeanServer.registerMBean( ab, name );
                }
            }

            m_allBeans.add( ab );

            log.info( "Registered new admin bean " + ab.getTitle() );
        } catch( final InstanceAlreadyExistsException e ) {
            log.error( "Admin bean already registered to JMX", e );
        } catch( final MBeanRegistrationException e ) {
            log.error( "Admin bean cannot be registered to JMX", e );
        } catch( final NotCompliantMBeanException e ) {
            log.error( "Your admin bean is not very good", e );
        } catch( final MalformedObjectNameException e ) {
            log.error( "Your admin bean name is not very good", e );
        } catch( final NullPointerException e ) {
            log.error( "Evil NPE occurred", e );
        }
    }

    private ObjectName getObjectName( final AdminBean ab ) throws MalformedObjectNameException {
        final String component = getJMXTitleString( ab.getType() );
        final String title     = ab.getTitle();
        return new ObjectName( Release.APPNAME + ":component=" + component + ",name=" + title );
    }

    /**
     *  Registers all the beans from a collection of WikiModuleInfos.  If some of the beans fail, logs the message and keeps going to the
     *  next bean.
     *
     *  @param c Collection of WikiModuleInfo instances
     */
    private void registerBeans( final Collection< WikiModuleInfo > c ) {
        for( final WikiModuleInfo wikiModuleInfo : c ) {
            final String abname = wikiModuleInfo.getAdminBeanClass();
            try {
                if( abname != null && abname.length() > 0 ) {
                    final Class< ? > abclass = Class.forName( abname );
                    final AdminBean ab = ( AdminBean )abclass.newInstance();
                    registerAdminBean( ab );
                }
            } catch( final ClassNotFoundException | InstantiationException | IllegalAccessException e ) {
                log.error( e.getMessage(), e );
            }
        }

    }

    // FIXME: Should unload the beans first.
    private void reload() {
        m_allBeans = new ArrayList<>();

        try {
            registerAdminBean( new CoreBean( m_engine ) );
            registerAdminBean( new UserBean( m_engine ) );
            registerAdminBean( new SearchManagerBean( m_engine ) );
            registerAdminBean( new PluginBean( m_engine ) );
            registerAdminBean( new FilterBean( m_engine ) );
        } catch( final NotCompliantMBeanException e ) {
            log.error( e.getMessage(), e );
        }
        for( final ModuleManager moduleManager : m_engine.getManagers( ModuleManager.class ) ) {
            registerBeans( moduleManager.modules() );
        }
    }

    /* (non-Javadoc)
	 * @see org.apache.wiki.ui.admin.AdminBeanManager#getAllBeans()
	 */
    @Override
	public List< AdminBean > getAllBeans() {
        if( m_allBeans == null ) {
        	reload();
        }

        return m_allBeans;
    }

    /* (non-Javadoc)
	 * @see org.apache.wiki.ui.admin.AdminBeanManager#findBean(java.lang.String)
	 */
    @Override
	public AdminBean findBean( final String id ) {
        for( final AdminBean ab : m_allBeans ) {
            if( ab.getId().equals( id ) ) {
                return ab;
            }
        }

        return null;
    }

    /**
     *  Provides a JDK 1.5-compliant version of the MBeanServerFactory. This will simply bind to the
     *  platform MBeanServer.
     */
    private static final class MBeanServerFactory15 {
        private MBeanServerFactory15()
        {}

        public static MBeanServer getServer() {
            return ManagementFactory.getPlatformMBeanServer();
        }
    }

    /**
     *  Returns the type identifier for a string type.
     *
     *  @param type A type string.
     *  @return A type value.
     */
    @Override
	public int getTypeFromString( final String type ) {
        if( "core".equals( type ) ) {
            return AdminBean.CORE;
        } else if( "editors".equals( type ) ) {
            return AdminBean.EDITOR;
        }

        return AdminBean.UNKNOWN;
    }

    /* (non-Javadoc)
	 * @see org.apache.wiki.ui.admin.AdminBeanManager#actionPerformed(org.apache.wiki.event.WikiEvent)
	 */
    @Override
	public void actionPerformed( final WikiEvent event ) {
        if( event instanceof WikiEngineEvent ) {
            if( event.getType() == WikiEngineEvent.SHUTDOWN ) {
                for( final AdminBean m_allBean : m_allBeans ) {
                    try {
                        final ObjectName on = getObjectName( m_allBean );
                        if( m_mbeanServer.isRegistered( on ) ) {
                            m_mbeanServer.unregisterMBean( on );
                            log.info( "Unregistered AdminBean " + m_allBean.getTitle() );
                        }
                    } catch( final MalformedObjectNameException e ) {
                        log.error( "Malformed object name when unregistering", e );
                    } catch( final InstanceNotFoundException e ) {
                        log.error( "Object was registered; yet claims that it's not there", e );
                    } catch( final MBeanRegistrationException e ) {
                        log.error( "Registration exception while unregistering", e );
                    }
                }
            }
        }
    }

}
