/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * This software is the proprietary information of Sun Microsystems, Inc.
 * Use is subject to license terms.
 *
 * Copyright 2004 Sun Microsystems, Inc.  Tous droits réservés.
 * Ce logiciel est propriété de Sun Microsystems, Inc.
 * Distribué par des licences qui en restreignent l'utilisation.
 *
 * ident        "@(#)CIBMonitoredObject.java 1.30     04/07/15 SMI"
 *
 */

package com.sun.mfwk.cib;

import com.sun.mfwk.cib.CIBMonitoredObjectMBean;
import com.sun.mfwk.cib.CIBMonitoredObjectIf;
import com.sun.mfwk.cib.CIBManagedObject;
import com.sun.mfwk.cib.providers.CIBProviderHandler;
import com.sun.mfwk.cib.statistics.CIBPerfStats;
import com.sun.mfwk.cib.states.CIBState;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.j2ee.statistics.Stats;

/**
 * Default implementation of a CIB Monitored Object MBean.
 */
public abstract class CIBMonitoredObject
    extends CIBManagedObject
    implements CIBMonitoredObjectMBean, CIBMonitoredObjectIf {

  private boolean stateProvisionInitedOnce = false;
  private boolean statisticProvisionInitedOnce = false;

    protected boolean isCurrentlyProvidingState = true;
    protected boolean isCurrentlyProvidingStatistics = true;
  protected CIBProviderHandler myProviderHandler = null;

  // operational, availability, and event generation
  protected int opStatus = -1;
  protected int availStatus = -1;
  protected long eventNumber = 0;

  // to be refined in subclasses

  abstract protected void retrieveStateProviders() throws CIBException;
  abstract protected void initStateProviders();
  abstract protected void startStateProviders();
  abstract protected void stopStateProviders();
  abstract protected void destroyStateProviders();

  abstract protected void retrieveStatisticProviders() throws CIBException;
  abstract protected void initStatisticProviders();
  abstract protected void startStatisticProviders();
  abstract protected void stopStatisticProviders();
  abstract protected void destroyStatisticProviders();

  //Constructors section
  public CIBMonitoredObject() {
  }



  abstract protected void retrieveConfigurationProviders() throws CIBException;
  abstract protected void initConfigurationProviders();
  abstract protected void startConfigurationProviders();
  abstract protected void stopConfigurationProviders();
  abstract protected void destroyConfigurationProviders();


  /**
   * Returns true, indicates that this managed object implements the State model and is
   * state manageable as described in "StateManagement" chapter of this specification.
   * Returns false, the managed object does not support state model.
   * @return boolean
   */
  public boolean isStateProvider() {
    return isCurrentlyProvidingState;
  }

  /**
   * Returns true, indicates that the managed object supports the generation of performance
   * statistics and implements the StatisticsProvider model as described in the
   * "StatisticsProvider" chapter of this specification.
   * Returns false, the managed object does not support performance statistics.
   * @return boolean
   */
  public boolean isStatisticProvider() {
    return isCurrentlyProvidingStatistics;
  }

  /**
   * enables/disables the generation of performance
   * statistics data in the supplier application.
   * This operation has no effect if the statisticsProvider attribute is false.
   * @param val boolean
   */
  public void setStateProvider(boolean val) throws CIBException {
    if (myProviderHandler == null)
    throw new CIBException("Monitored Object cannot set state provider, ProviderHandler is undefined");

    try {

        if ((val != isCurrentlyProvidingState) ||
            (!stateProvisionInitedOnce)) {

        retrieveStateProviders();
        if ( val ) {
          startStateProviders();
          initStateProviders();
        }
        else {
          stopStateProviders();
          destroyStateProviders();
        }
        isCurrentlyProvidingState = val;
        stateProvisionInitedOnce = true;
      }
    }
    catch (CIBException e) {
      CIBMbeanLogger.warning(CIBMbeanLogMessageHeaderString + "Caught CIBException : \n" +
                             "while changing state provider status in " +
                            this + CIBMbeanNewLine + CIBMbeanLogMessageClosingString);
      throw e;
    }
  }

  /**
   * enables/disables the generation of performance statistics
   * data in the supplier application. The effect of invoking that operation should
   * be a near zero data generation overhead in the supplier application.
   * This operation has no effect if the statisticsProvider attribute is false.
   * @param val boolean
   */
  public void setStatisticProvider(boolean val) throws CIBException {
    if (myProviderHandler == null)
    throw new CIBException("Monitored Object cannot set state provider, ProviderHandler is undefined");

    try {
      if ((val != isCurrentlyProvidingStatistics) ||
          (!statisticProvisionInitedOnce)) {

        retrieveStatisticProviders();
        if ( val ) {
          startStatisticProviders();
          initStatisticProviders();
        }
        else {
          stopStatisticProviders();
          destroyStatisticProviders();
        }
        isCurrentlyProvidingStatistics = val;
        statisticProvisionInitedOnce = true;
      }
    }
    catch (CIBException e) {
      CIBMbeanLogger.warning(CIBMbeanLogMessageHeaderString + "Caught CIBException : \n" +
                             "while changing statistic provider status in " +
                            this + CIBMbeanNewLine + CIBMbeanLogMessageClosingString);
      throw e;
    }
  }

  /**
   * Returns the CIBProviderHandler
   * @return CIBProviderHandler
   */
  public CIBProviderHandler getCIBProviderHandler() throws CIBProviderHandlerNotFoundException {
    if ( isStateProvider() || isStatisticProvider()) return myProviderHandler;
    else if (myProviderHandler != null) return myProviderHandler;
    else if (myProviderHandler == null) {
      String message = " Unset Provider Handler while providing state or statitic in monitored object : \n";
      CIBMbeanLogger.info(CIBMbeanLogMessageHeaderString + message +
                          this + CIBMbeanNewLine + CIBMbeanLogMessageClosingString);
      throw new CIBProviderHandlerNotFoundException(message, null);
    }
    return null;
  }

  /**
   * Set the Provider handler for the CIB Object
   * @param providerHandler CIBProviderHanlder
   */
  public void setCIBProviderHandler(CIBProviderHandler providerHandler) {
    myProviderHandler = providerHandler;
  }

  /**
   * Gets a CIB Statistic as a standard serializable JMX Open Type
   *
   * @param name String
   * @return CompositeData[]
   */
  public abstract CompositeData getOpenStatistic(String name) throws CIBAttributeNotFoundException, CIBException;

  /**
   *  Gets all CIBStatistics encoded as serializable JMX Open Types.
   *  If no statistics is found null is returned.
   *
   * @param names String[]
   * @return CompositeData[]
   */
  public abstract CompositeData[] getOpenStatistics(String[] names) throws CIBException;

  /**
   * Gets a CIBStats object encoded as a standard serializable JMX Open Type
   *
   * @return javax.management.openmbean.CompositeData
   */
  public abstract CompositeData getOpenStats() throws CIBException;

  /**
   * Gets all available statistic names
   *
   * @return String[]
   */
  public abstract String[] getStatisticNames() throws CIBException;

  /**
   * Gets a CIBStats object for all available statistics.
   *
   * @return javax.management.j2ee.statistics.Stats
   */
  public abstract Stats getStats() throws CIBException;

}
