/* 
 * 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.felix.ipojo.handlers.lifecycle.callback;

import java.lang.reflect.InvocationTargetException;
import java.util.Dictionary;

import org.apache.felix.ipojo.ComponentInstance;
import org.apache.felix.ipojo.ConfigurationException;
import org.apache.felix.ipojo.InstanceManager;
import org.apache.felix.ipojo.PrimitiveHandler;
import org.apache.felix.ipojo.metadata.Element;
import org.apache.felix.ipojo.parser.MethodMetadata;
import org.apache.felix.ipojo.parser.PojoMetadata;

/**
 * Lifecycle callback handler.
 * 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class LifecycleCallbackHandler extends PrimitiveHandler {

    /**
     * The list of the callback of the component.
     */
    private LifecycleCallback[] m_callbacks = new LifecycleCallback[0];

    /**
     * State of the instance manager (unresolved at the beginning).
     */
    private int m_state = InstanceManager.INVALID;
    /**
     * Does a POJO object be created at starting.
     */
    private boolean m_immediate = false;

    /**
     * Add the given callback to the callback list.
     * 
     * @param callback : the element to add
     */
    private void addCallback(LifecycleCallback callback) {
        for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
            if (m_callbacks[i] == callback) {
                return;
            }
        }

        if (m_callbacks != null && m_callbacks.length > 0) { //TODO check here if we can improve the test
            LifecycleCallback[] newHk = new LifecycleCallback[m_callbacks.length + 1];
            System.arraycopy(m_callbacks, 0, newHk, 0, m_callbacks.length);
            newHk[m_callbacks.length] = callback;
            m_callbacks = newHk;
        } else {
            m_callbacks = new LifecycleCallback[] { callback };
        }
    }

    /**
     * Configure the handler.
     * @param metadata : the component type metadata
     * @param configuration : the instance configuration
     * @throws ConfigurationException : one callback metadata is not correct (either the transition or the method are not correct).
     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
     */
    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
        m_callbacks = new LifecycleCallback[0];

        String imm = metadata.getAttribute("immediate");
        m_immediate = imm != null && imm.equalsIgnoreCase("true");
        
        PojoMetadata meta = getFactory().getPojoMetadata();

        Element[] hooksMetadata = metadata.getElements("callback");
        for (int i = 0; hooksMetadata != null && i < hooksMetadata.length; i++) {
            String method = hooksMetadata[i].getAttribute("method");
            if (method == null) {
                throw new ConfigurationException("Lifecycle callback : A callback needs to contain a method attribute");
            }
            
            MethodMetadata met = meta.getMethod(method, new String[0]);
            
            int transition = -1;
            String trans = hooksMetadata[i].getAttribute("transition");
            if (trans == null) {
                throw new ConfigurationException("Lifecycle callback : the transition attribute is missing");
            } else {
                if (trans.equalsIgnoreCase("validate")) {
                    transition = LifecycleCallback.VALIDATE;
                } else if (trans.equalsIgnoreCase("invalidate")) {
                    transition = LifecycleCallback.INVALIDATE; 
                } else {
                    throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition : " + trans);
                }
            }
            
            LifecycleCallback callback = null;
            if (met == null) {
                callback = new LifecycleCallback(this, transition, method);
            } else {
                callback = new LifecycleCallback(this, transition, met);
            }
            addCallback(callback);
        }
    }

    /**
     * Start the handler. 
     * @see org.apache.felix.ipojo.Handler#start()
     */
    public void start() {
     // Do nothing during the start
    } 

    /**
     * Stop the handler.
     * @see org.apache.felix.ipojo.Handler#stop()
     */
    public void stop() {
        m_state = InstanceManager.INVALID;
    }

    /**
     * When the state change call the associated callback.
     * 
     * @param state : the new instance state.
     * @see org.apache.felix.ipojo.Handler#stateChanged(int)
     */
    public void stateChanged(int state) {
        int transition = -1;
        if (m_state == ComponentInstance.INVALID && state == ComponentInstance.VALID) {
            transition = LifecycleCallback.VALIDATE;
        }
        if (m_state == ComponentInstance.VALID && state == ComponentInstance.INVALID) {
            transition = LifecycleCallback.INVALIDATE;
        }
        
        // Manage immediate component
        if (m_immediate && transition == LifecycleCallback.VALIDATE && getInstanceManager().getPojoObjects() == null) {
            getInstanceManager().getPojoObject();
        }

        for (int i = 0; i < m_callbacks.length; i++) {
            if (m_callbacks[i].getTransition() == transition) {
                try {
                    m_callbacks[i].call();
                } catch (NoSuchMethodException e) {
                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not found");
                    throw new IllegalStateException(e);
                } catch (IllegalAccessException e) {
                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not accessible");
                    throw new IllegalStateException(e);
                } catch (InvocationTargetException e) {
                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " has thrown an exception : " + e.getTargetException().getMessage(), e.getTargetException());
                    throw new IllegalStateException(e.getTargetException());
                }
            }
        }
        // Update to internal state
        m_state = state;
    }
}
