/*
 * 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.geode.admin.jmx.internal;

import javax.management.Notification;
import javax.management.ObjectName;
import javax.management.modelmbean.ModelMBean;
import javax.naming.OperationNotSupportedException;

import org.apache.commons.modeler.ManagedBean;
import org.apache.logging.log4j.Logger;

import org.apache.geode.CancelException;
import org.apache.geode.SystemFailure;
import org.apache.geode.admin.AdminException;
import org.apache.geode.admin.Statistic;
import org.apache.geode.internal.admin.StatResource;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * Provides MBean support for the monitoring of a statistic resource.
 *
 * @since GemFire 3.5
 *
 */
public class StatisticResourceJmxImpl extends org.apache.geode.admin.internal.StatisticResourceImpl
    implements javax.management.NotificationListener,
    org.apache.geode.admin.jmx.internal.ManagedResource {

  private static final Logger logger = LogService.getLogger();

  /**
   * Interval in seconds between refreshes. Values less than one results in no refreshing .
   */
  private int refreshInterval = 0;

  /** The JMX object name of this managed resource */
  private ObjectName objectName;

  /** A flag to indicate if time is inited. MBeanUtil lookup is costly */
  private boolean timerInited = false;

  // -------------------------------------------------------------------------
  // Constructor(s)
  // -------------------------------------------------------------------------

  /**
   * Constructor for the StatisticResource object
   *
   * @param statResource the admin StatResource to manage/monitor
   * @param member the SystemMember owning this resource
   * @exception org.apache.geode.admin.AdminException if unable to create this StatisticResource for
   *            administration
   */
  public StatisticResourceJmxImpl(StatResource statResource, SystemMemberJmx member)
      throws org.apache.geode.admin.AdminException {
    super(statResource, member);
    initializeMBean();
  }

  /** Create and register the MBean to manage this resource */
  private void initializeMBean() throws org.apache.geode.admin.AdminException {
    this.mbeanName = new StringBuffer("GemFire.Statistic:").append("source=")
        .append(MBeanUtil.makeCompliantMBeanNameProperty(this.member.getId())).append(",type=")
        .append(MBeanUtil.makeCompliantMBeanNameProperty(getType())).append(",name=")
        .append(MBeanUtil.makeCompliantMBeanNameProperty(getName())).append(",uid=")
        .append(getUniqueId()).toString();

    this.objectName =
        MBeanUtil.createMBean(this, addDynamicAttributes(MBeanUtil.lookupManagedBean(this)));

    // Refresh Interval
    AdminDistributedSystemJmxImpl sysJmx =
        (AdminDistributedSystemJmxImpl) this.member.getDistributedSystem();
    if (sysJmx.getRefreshInterval() > 0)
      this.refreshInterval = sysJmx.getRefreshInterval();
  }

  // -------------------------------------------------------------------------
  // MBean attributes - accessors/mutators
  // -------------------------------------------------------------------------

  /**
   * Gets the interval in seconds between statistics refreshes
   *
   * @return the current refresh interval in seconds
   */
  public int getRefreshInterval() {
    return this.refreshInterval;
  }

  /**
   * Sets interval in seconds between statistic refreshes; zero or less turns off auto refreshing.
   * Manual refreshing has no effect on when the next scheduled refresh will occur.
   *
   * @param refreshInterval the new refresh interval in seconds
   */
  private void _setRefreshInterval(int refreshInterval) {
    boolean isRegistered = MBeanUtil.isRefreshNotificationRegistered(this,
        RefreshNotificationType.STATISTIC_RESOURCE_STATISTICS);

    if (isRegistered && (getRefreshInterval() == refreshInterval))
      return;

    try {
      MBeanUtil.registerRefreshNotification(this, // NotificationListener
          getMBeanName(), // User Data as MBean Name
          RefreshNotificationType.STATISTIC_RESOURCE_STATISTICS, refreshInterval); // int

      this.refreshInterval = refreshInterval;
      timerInited = true;
    } catch (RuntimeException e) {
      logger.warn(e.getMessage(), e); // dead in water, print, and then ignore
      this.refreshInterval = 0; // zero out to avoid more exceptions
    } catch (VirtualMachineError err) {
      SystemFailure.initiateFailure(err);
      // If this ever returns, rethrow the error. We're poisoned
      // now, so don't let this thread continue.
      throw err;
    } catch (Error e) {
      // Whenever you catch Error or Throwable, you must also
      // catch VirtualMachineError (see above). However, there is
      // _still_ a possibility that you are dealing with a cascading
      // error condition, so you also need to check to see if the JVM
      // is still usable:
      SystemFailure.checkFailure();
      logger.error(e.getMessage(), e); // dead in water, print, and then ignore
      this.refreshInterval = 0; // zero out to avoid more exceptions
    }
  }

  /**
   * RefreshInterval is now set only through the AdminDistributedSystem property refreshInterval.
   * Attempt to set refreshInterval on StatisticResourceJmx MBean would result in an
   * OperationNotSupportedException Auto-refresh is enabled on demand when a call to getStatistics
   * is made
   *
   * @param refreshInterval the new refresh interval in seconds
   * @deprecated since 6.0 use DistributedSystemConfig.refreshInterval instead
   */
  @Deprecated
  public void setRefreshInterval(int refreshInterval) throws OperationNotSupportedException {
    throw new OperationNotSupportedException(
        "RefreshInterval can not be set directly. Use DistributedSystemConfig.refreshInterval.");
  }

  // -------------------------------------------------------------------------
  // JMX Notification listener
  // -------------------------------------------------------------------------

  /**
   * Handles notification to refresh. Reacts by refreshing the values of this SystemMember's
   * ConfigurationParamaters. Any other notification is ignored. Given notification is handled only
   * if there is any JMX client connected to the system.
   * <p>
   * TODO: investigate use of NotificationFilter instead of explicit check...
   *
   * @param notification the JMX notification being received
   * @param hb handback object is unused
   */
  @Override
  public void handleNotification(Notification notification, Object hb) {
    AdminDistributedSystemJmxImpl adminDSJmx =
        (AdminDistributedSystemJmxImpl) this.member.getDistributedSystem();

    String typeStatResourceStats = RefreshNotificationType.STATISTIC_RESOURCE_STATISTICS.getType();

    if (typeStatResourceStats.equals(notification.getType())
        && getMBeanName().equals(notification.getUserData())
        && !adminDSJmx.isRmiClientCountZero()) {
      try {
        refresh();

      } catch (org.apache.geode.admin.AdminException e) {
        logger.warn(e.getMessage(), e);
      } catch (org.apache.geode.admin.OperationCancelledException e) {
        // underlying resource is no longer reachable by remote admin
        logger.warn(e.getMessage(), e);
        _setRefreshInterval(0);
      } catch (CancelException e) {
        // shutting down - okay to ignore
      } catch (java.lang.RuntimeException e) {
        logger.debug(e.getMessage(), e); // dead in water, print, and then ignore
        _setRefreshInterval(0); // zero out to avoid more exceptions
      } catch (VirtualMachineError err) {
        SystemFailure.initiateFailure(err);
        // If this ever returns, rethrow the error. We're poisoned
        // now, so don't let this thread continue.
        throw err;
      } catch (java.lang.Error e) {
        // Whenever you catch Error or Throwable, you must also
        // catch VirtualMachineError (see above). However, there is
        // _still_ a possibility that you are dealing with a cascading
        // error condition, so you also need to check to see if the JVM
        // is still usable:
        SystemFailure.checkFailure();
        logger.error(e.getMessage(), e); // dead in water, print, and then ignore
        this.refreshInterval = 0; // zero out to avoid more exceptions
      }
    }
  }

  // -------------------------------------------------------------------------
  // Create MBean attributes for each Statistic
  // -------------------------------------------------------------------------

  /**
   * Add MBean attribute definitions for each Statistic.
   *
   * @param managed the mbean definition to add attributes to
   * @return a new instance of ManagedBean copied from <code>managed</code> but with the new
   *         attributes added
   */
  ManagedBean addDynamicAttributes(ManagedBean managed)
      throws org.apache.geode.admin.AdminException {
    if (managed == null) {
      throw new IllegalArgumentException(
          "ManagedBean is null");
    }

    refresh(); // to get the stats...

    // need to create a new instance of ManagedBean to clean the "slate"...
    ManagedBean newManagedBean = new DynamicManagedBean(managed);
    for (int i = 0; i < this.statistics.length; i++) {
      StatisticAttributeInfo attrInfo = new StatisticAttributeInfo();

      attrInfo.setName(this.statistics[i].getName());
      attrInfo.setDisplayName(this.statistics[i].getName());
      attrInfo.setDescription(this.statistics[i].getDescription());
      attrInfo.setType("java.lang.Number");

      attrInfo.setIs(false);
      attrInfo.setReadable(true);
      attrInfo.setWriteable(false);

      attrInfo.setStat(this.statistics[i]);

      newManagedBean.addAttribute(attrInfo);
    }
    return newManagedBean;
  }

  @Override
  public Statistic[] getStatistics() {
    if (!timerInited) {
      // 1st call to getStatistics would trigger
      // the auto-refresh if an interval is set
      if (this.refreshInterval > 0) {
        this._setRefreshInterval(this.refreshInterval);
      }
    }

    if (this.statistics == null) {
      try {
        this.refresh();
      } catch (AdminException e) {
        this.statistics = new Statistic[0];
      }
    }

    return this.statistics;
  }

  // -------------------------------------------------------------------------
  // ManagedResource implementation
  // -------------------------------------------------------------------------

  /** The name of the MBean that will manage this resource */
  private String mbeanName;

  /** The ModelMBean that is configured to manage this resource */
  private ModelMBean modelMBean;

  @Override
  public String getMBeanName() {
    return this.mbeanName;
  }

  @Override
  public ModelMBean getModelMBean() {
    return this.modelMBean;
  }

  @Override
  public void setModelMBean(ModelMBean modelMBean) {
    this.modelMBean = modelMBean;
  }

  @Override
  public ObjectName getObjectName() {
    return this.objectName;
  }

  @Override
  public ManagedResourceType getManagedResourceType() {
    return ManagedResourceType.STATISTIC_RESOURCE;
  }

  @Override
  public void cleanupResource() {
    this.modelMBean = null;
    this.member = null;
    this.statistics = null;
    this.statResource = null;
  }

  /**
   * Checks equality of the given object with <code>this</code> based on the type (Class) and the
   * MBean Name returned by <code>getMBeanName()</code> methods.
   *
   * @param obj object to check equality with
   * @return true if the given object is if the same type and its MBean Name is same as
   *         <code>this</code> object's MBean Name, false otherwise
   */
  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof StatisticResourceJmxImpl)) {
      return false;
    }

    StatisticResourceJmxImpl other = (StatisticResourceJmxImpl) obj;

    return this.getMBeanName().equals(other.getMBeanName());
  }

  /**
   * Returns hash code for <code>this</code> object which is based on the MBean Name generated.
   *
   * @return hash code for <code>this</code> object
   */
  @Override
  public int hashCode() {
    return this.getMBeanName().hashCode();
  }
}
