/*
 * 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 flex.management;

import java.util.Date;

import flex.messaging.FlexComponent;
import flex.messaging.config.ConfigMap;
import flex.messaging.config.ConfigurationException;
import flex.messaging.log.Log;

/**
 * An abstract base class that implements the <code>Manageable</code> and <code>FlexComponent</code> interfaces.
 * This is an excellent starting point for a server component that may be instantiated, initialized, started and
 * stopped, as well as exposing an optional management interface via a peer MBean.
 * <p>Support for changing component properties while the component is
 * started should be determined on a per-property basis, and the started property is volatile to ensure consistent
 * reads of the start state of the component across threads. This class performs no synchronization and is not safe for modification by multiple concurrent threads
 * in the absence of external synchronization.
 * </p>
 */
public abstract class ManageableComponent implements Manageable, FlexComponent
{
    //--------------------------------------------------------------------------
    //
    // Protected Static Constants
    //
    //--------------------------------------------------------------------------

    /**
     * Error code for attempting to change a property after starting.
     */
    protected static final int PROPERTY_CHANGE_AFTER_STARTUP = 11115;

    /**
     * Error code to alert the user that a required component property is null.
     */
    protected static final int NULL_COMPONENT_PROPERTY = 11116;

    //--------------------------------------------------------------------------
    //
    // Constructor
    //
    //--------------------------------------------------------------------------

    /**
     * Constructs a <code>ManageableComponent</code> instance, specifying
     * whether to enable management.
     * Enabling management will trigger the creation of a peer MBean that exposes the
     * management interface for this component.
     *
     * @param enableManagement <code>true</code> to enable management, <code>false</code> to disable
     * management.
     */
    public ManageableComponent(boolean enableManagement)
    {
        setManaged(enableManagement);
    }

    //--------------------------------------------------------------------------
    //
    // Public Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  control
    //----------------------------------

    /**
     * The peer MBean of the <code>ManageableComponent</code> that exposes a management interface.
     */
    protected BaseControl control;

    /**
     * (non-JavaDoc)
     * @see Manageable#getControl()
     */
    public BaseControl getControl()
    {
        return control;
    }

    /**
     * (non-JavaDoc)
     * @see Manageable#setControl(BaseControl)
     */
    public void setControl(BaseControl control)
    {
        this.control = control;
    }

    //----------------------------------
    //  id
    //----------------------------------

    /**
     * The internal id value of the <code>ManageableComponent</code>.
     */
    protected String id;

    /**
     * Returns the id of the <code>ManageableComponent</code>.
     *
     * @return The id of the <code>ManageableComponent</code>.
     */
    public String getId()
    {
        return id;
    }

    /**
     * Sets the id of the <code>ManageableComponent</code>. The id cannot be
     * null and it cannot be changed after startup.
     *
     * @param id The id of the <code>ManageableComponent</code>.
     */
    public void setId(String id)
    {
        if (isStarted())
        {
            blockAssignmentWhileStarted("id");
        }
        if (id == null)
        {
            // Id of a component cannot be null.
            blockNullAssignment("id");
        }
        this.id = id;
    }

    //----------------------------------
    //  managed
    //----------------------------------

    /**
     * The internal managed flag of the <code>ManageableComponent</code>.
     */
    protected volatile boolean managed;

    /**
     * (non-JavaDoc)
     * @see Manageable#isManaged()
     */
    public boolean isManaged()
    {
        return managed;
    }

    /**
     * Enables or disables management for the component. Management cannot be
     * changed once the component is started and management cannot be
     * <code>true</code> if the parent of the component is not managed.
     *
     * @param enableManagement <code>true</code> to enable management, <code>false</code> to disable management.
     */
    public void setManaged(boolean enableManagement)
    {
        if (isStarted() && control != null)
        {
            blockAssignmentWhileStarted("managed");
        }
        if (enableManagement && parent != null && !parent.isManaged())
        {
            if (Log.isWarn())
            {
                Log.getLogger(getLogCategory()).warn("Component: '" + id + "' cannot be managed" +
                " since its parent is unmanaged.");
            }
            return;
        }
        managed = enableManagement;
    }

    //----------------------------------
    //  parent
    //----------------------------------

    /**
     * The internal reference to the parent component (if any) of the <code>ManageableComponent</code>.
     */
    protected Manageable parent;

    /**
     * Returns the parent of the component.
     *
     * @return The parent of the component.
     */
    public Manageable getParent()
    {
        return parent;
    }

    /**
     * Sets the parent of the component. The parent cannot be changed
     * after component startup and it cannot be null.
     *
     * @param parent The parent of the component.
     */
    public void setParent(Manageable parent)
    {
        if (isStarted())
        {
            blockAssignmentWhileStarted("parent");
        }
        if (parent == null)
        {
            // Parent of a component cannot be null.
            blockNullAssignment("parent");
        }
        if (!parent.isManaged() && isManaged())
        {
            if (Log.isWarn())
            {
                Log.getLogger(getLogCategory()).warn("Component: '" + id + "' cannot be managed" +
                        " since its parent is unmanaged.");
            }
            setManaged(false);
        }
        this.parent = parent;
    }

    //----------------------------------
    //  started
    //----------------------------------

    /**
     * The internal started flag of the <code>ManageableComponent</code>.
     */
    protected volatile boolean started;

    /**
     * Returns if the component is started or not.
     *
     * @return <code>true</code> if the component is started.
     */
    public boolean isStarted()
    {
        return started;
    }

    /**
     * Sets if the component is started.
     *
     * @param started true if the component is started.
     */
    protected void setStarted(boolean started)
    {
        if (this.started != started)
        {
            this.started = started;
            if (started && control != null)
            {
                control.setStartTimestamp(new Date());
            }
        }
    }

    //----------------------------------
    //  valid
    //----------------------------------

    /**
     * The internal valid flag of the <code>ManageableComponent</code>.
     */
    protected boolean valid;

    /**
     * Returns if the component is valid.
     *
     * @return <code>true</code> if the component is valid.
     */
    public boolean isValid()
    {
        return valid;
    }

    /**
     * Sets if the component is valid.
     *
     * @param valid true if the comoponent is valid.
     */
    protected void setValid(boolean valid)
    {
        this.valid = valid;
    }

    //----------------------------------
    //  logCategory
    //----------------------------------

    /**
     * Returns the log category of the component. Subclasses must provide an
     * implementation that returns their desired log category.
     *
     * @return The log category of the component.
     */
    protected abstract String getLogCategory();

    //--------------------------------------------------------------------------
    //
    // Public Methods
    //
    //--------------------------------------------------------------------------

    /**
     * Invoked to initialize the <code>ManageableComponent</code>.
     * This base implementation calls <code>setId()</code> passing the provided
     * id and ignores the properties map argument.
     * Subclasses should call <code>super.initialize()</code>.
     *
     * @param id Id of the <code>ManageableComponent</code>.
     * @param properties Properties for the <code>ManageableComponent</code>.
     */
    public void initialize(String id, ConfigMap properties)
    {
        setId(id);
    }

    /**
     * Validates and starts the component.
     *
     * Subclasses should call <code>super.start()</code>.
     */
    public void start()
    {
        validate();
        setStarted(true);
    }

    /**
     * Invalidates and stops the component.
     *
     * Subclasses should call <code>super.stop()</code>.
     */
    public void stop()
    {
        invalidate();
        setStarted(false);
    }

    //--------------------------------------------------------------------------
    //
    // Protocted Methods
    //
    //--------------------------------------------------------------------------

    /**
     * Convenience method that may be used to generate and throw an Exception for an attempt to set the specified property if the
     * component is started.
     *
     * @param propertyName The name of the property being incorrectly assigned; included in the Exception message.
     */
    protected void blockAssignmentWhileStarted(String propertyName)
    {
        ConfigurationException ce = new ConfigurationException();
        ce.setMessage(PROPERTY_CHANGE_AFTER_STARTUP, new Object[]{propertyName});
        throw ce;
    }

    /**
     * Convenience method that may be used to generate and throw an Exception for an attempt to assign a null value to a property that
     * requires non-null values.
     *
     * @param propertyName The name of the property being incorrectly assigned.
     */
    protected void blockNullAssignment(String propertyName)
    {
        ConfigurationException ce = new ConfigurationException();
        ce.setMessage(NULL_COMPONENT_PROPERTY, new Object[]{propertyName});
        throw ce;
    }

    /**
     * Invoked from within the <code>stop()</code> method to invalidate the component as part of shutdown.
     * This base implementation sets the valid property to false.
     * Subclasses should call <code>super.invalidate()</code>.
     */
    protected void invalidate()
    {
        setValid(false);
    }

    /**
     * Hook method invoked from within the <code>start()</code> method to validate that the component is in a
     * startable state.
     * This base implementation validates the component by ensuring it has an id and a parent and then sets
     * the valid property to true.
     * If the component is not in a valid, startable state an Exception is thrown.
     * Subclasses should call <code>super.validate()</code>.
     */
    protected void validate()
    {
        if (getId() == null)
        {
            // Id of a component cannot be null.
            blockNullAssignment("id");
        }
        if (getParent() == null)
        {
            // Parent of a component cannot be null.
            blockNullAssignment("parent");
        }
        setValid(true);
    }

}
