/*
 * 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 java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.management.MalformedObjectNameException;
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.admin.AdminException;
import org.apache.geode.admin.CacheServerConfig;
import org.apache.geode.admin.CacheVmConfig;
import org.apache.geode.admin.ConfigurationParameter;
import org.apache.geode.admin.StatisticResource;
import org.apache.geode.admin.SystemMemberCache;
import org.apache.geode.admin.SystemMemberCacheEvent;
import org.apache.geode.admin.SystemMemberRegionEvent;
import org.apache.geode.admin.internal.CacheServerImpl;
import org.apache.geode.admin.internal.ConfigurationParameterImpl;
import org.apache.geode.internal.admin.ClientMembershipMessage;
import org.apache.geode.internal.admin.GemFireVM;
import org.apache.geode.internal.admin.StatResource;
import org.apache.geode.internal.logging.LogService;

/**
 * MBean representation of a {@link org.apache.geode.admin.CacheVm}.
 *
 * @since GemFire 4.0
 */
public class CacheServerJmxImpl extends CacheServerImpl
    implements ManagedResource, CacheVmConfig, CacheServerConfig, SystemMemberJmx {

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

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

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

  /** 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;

  /** Reference to the cache MBean representing a Cache in the Cache VM Member */
  private SystemMemberCacheJmxImpl managedSystemMemberCache;

  /** collection to collect all the resources created for this member */
  private Map<StatResource, StatisticResourceJmxImpl> managedStatisticsResourcesMap =
      new HashMap<StatResource, StatisticResourceJmxImpl>();

  ////////////////////// Constructors //////////////////////

  /**
   * Creates a new <code>CacheServerJmxImpl</code> for an existing cache server.
   */
  CacheServerJmxImpl(AdminDistributedSystemJmxImpl system, GemFireVM vm) throws AdminException {

    super(system, vm);
    initializeMBean();
  }

  /**
   * Creates a new <code>CacheServerJmxImpl</code> for an newly-created cache server.
   */
  CacheServerJmxImpl(AdminDistributedSystemJmxImpl system, CacheVmConfig config)
      throws AdminException {

    super(system, config);
    initializeMBean();
  }

  ////////////////////// Instance Methods //////////////////////

  /**
   * Creates and registers the MBean to manage this resource
   */
  private void initializeMBean() throws AdminException {
    this.mbeanName = new StringBuffer("GemFire.CacheVm:").append("id=")
        .append(MBeanUtil.makeCompliantMBeanNameProperty(getId())).append(",type=")
        .append(MBeanUtil.makeCompliantMBeanNameProperty(getType().getName())).toString();

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

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

  @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.CACHE_VM;
  }

  /**
   * Un-registers all the statistics & cache managed resource created for this member. After
   * un-registering the resource MBean instances, clears managedStatisticsResourcesMap collection &
   * sets managedSystemMemberCache to null.
   *
   * Creates ConfigurationParameterJmxImpl, StatisticResourceJmxImpl and SystemMemberCacheJmxImpl.
   * But cleans up only StatisticResourceJmxImpl and SystemMemberCacheJmxImpl which are of type
   * ManagedResource.
   */
  @Override
  public void cleanupResource() {
    synchronized (this.managedStatisticsResourcesMap) {
      ConfigurationParameter[] names = getConfiguration();
      if (names != null) {
        for (int i = 0; i < names.length; i++) {
          ConfigurationParameter parm = names[i];
          ((ConfigurationParameterImpl) parm).removeConfigurationParameterListener(this);
        }
      }
      this.parms.clear();

      Collection<StatisticResourceJmxImpl> statisticResources =
          managedStatisticsResourcesMap.values();

      for (StatisticResourceJmxImpl statisticResource : statisticResources) {
        MBeanUtil.unregisterMBean(statisticResource);
      }

      this.managedStatisticsResourcesMap.clear();
    }

    MBeanUtil.unregisterMBean(this.managedSystemMemberCache);
    this.managedSystemMemberCache = null;
  }

  /////////////////////// Configuration ///////////////////////

  @Override
  public String getHost() {
    return this.getConfig().getHost();
  }

  @Override
  public void setHost(String host) {
    this.getConfig().setHost(host);
  }

  @Override
  public String getWorkingDirectory() {
    return this.getConfig().getWorkingDirectory();
  }

  @Override
  public void setWorkingDirectory(String dir) {
    this.getConfig().setWorkingDirectory(dir);
  }

  @Override
  public String getProductDirectory() {
    return this.getConfig().getProductDirectory();
  }

  @Override
  public void setProductDirectory(String dir) {
    this.getConfig().setProductDirectory(dir);
  }

  @Override
  public String getRemoteCommand() {
    return this.getConfig().getRemoteCommand();
  }

  @Override
  public void setRemoteCommand(String remoteCommand) {
    this.getConfig().setRemoteCommand(remoteCommand);
  }

  @Override
  public void validate() {
    throw new UnsupportedOperationException("Should not be invoked");
  }

  @Override
  public Object clone() throws CloneNotSupportedException {
    throw new UnsupportedOperationException("Should not be invoked");
  }

  @Override
  public String getCacheXMLFile() {
    return this.getConfig().getCacheXMLFile();
  }

  @Override
  public void setCacheXMLFile(String cacheXMLFile) {
    this.getConfig().setCacheXMLFile(cacheXMLFile);
  }

  @Override
  public String getClassPath() {
    return this.getConfig().getClassPath();
  }

  @Override
  public void setClassPath(String classpath) {
    this.getConfig().setClassPath(classpath);
  }

  // -------------------------------------------------------------------------
  // MBean attribute accessors/mutators
  // -------------------------------------------------------------------------

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

  /**
   * Sets interval in seconds between cache config 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
   */
  @Override
  public void _setRefreshInterval(int refreshInterval) {
    boolean isRegistered = MBeanUtil.isRefreshNotificationRegistered(this,
        RefreshNotificationType.SYSTEM_MEMBER_CONFIG);

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

    this.refreshInterval = Helper.setAndReturnRefreshInterval(this, refreshInterval);
  }

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

  // -------------------------------------------------------------------------
  // MBean Operations
  // -------------------------------------------------------------------------

  @Override
  public void refreshConfig() throws org.apache.geode.admin.AdminException {
    // 1st call to refreshConfig would trigger
    // the auto-refresh if an interval is set
    if (this.refreshInterval > 0) {
      this._setRefreshInterval(this.refreshInterval);
    }

    super.refreshConfig();
  }

  /**
   * Gets this member's cache.
   *
   * @return array of ObjectName for this member's cache
   */
  @Override
  public ObjectName manageCache() throws AdminException, MalformedObjectNameException {
    return Helper.manageCache(this);
  }

  /**
   * Gets all active StatisticResources for this manager.
   *
   * @return array of ObjectName instances
   */
  @Override
  public ObjectName[] manageStats() throws AdminException, MalformedObjectNameException {
    return Helper.manageStats(this);
  }

  /**
   * Gets the active StatisticResources for this manager, based on the typeName as the key
   *
   * @return ObjectName of StatisticResourceJMX instance
   */
  @Override
  public ObjectName[] manageStat(String statisticsTypeName)
      throws AdminException, MalformedObjectNameException {

    return Helper.manageStat(this, statisticsTypeName);
  }

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

  /**
   * Handles notification to refresh. Reacts by refreshing the values of this GemFireManager's
   * ConfigurationParamaters. Any other notification is ignored. Given notification is handled only
   * if there is any JMX client connected to the system.
   *
   * @param notification the JMX notification being received
   * @param hb handback object is unused
   */
  @Override
  public void handleNotification(Notification notification, Object hb) {
    AdminDistributedSystemJmxImpl systemJmx = (AdminDistributedSystemJmxImpl) this.system;

    if (!systemJmx.isRmiClientCountZero()) {
      Helper.handleNotification(this, notification, hb);
    }
  }

  // -------------------------------------------------------------------------
  // Template methods overriden from superclass...
  // -------------------------------------------------------------------------

  /**
   * Template method for creating instance of ConfigurationParameter. Overridden to return
   * ConfigurationParameterJmxImpl.
   */
  @Override
  protected ConfigurationParameter createConfigurationParameter(String name, String description,
      Object value, Class type, boolean userModifiable) {
    return new ConfigurationParameterJmxImpl(name, description, value, type, userModifiable);
  }



  /**
   * Override createStatisticResource by instantiating StatisticResourceJmxImpl if it was not
   * created earlier otherwise returns the same instance.
   *
   * @param stat StatResource reference for which this JMX resource is to be created
   * @return StatisticResourceJmxImpl - JMX Implementation of StatisticResource
   * @throws AdminException if constructing StatisticResourceJmxImpl instance fails
   */
  @Override
  protected StatisticResource createStatisticResource(StatResource stat)
      throws org.apache.geode.admin.AdminException {
    StatisticResourceJmxImpl managedStatisticResource = null;

    synchronized (this.managedStatisticsResourcesMap) {
      /*
       * Ensuring that a single instance of Statistic Resource is created per StatResource.
       */
      StatisticResourceJmxImpl statisticResourceJmxImpl = managedStatisticsResourcesMap.get(stat);
      if (statisticResourceJmxImpl != null) {
        managedStatisticResource = statisticResourceJmxImpl;
      } else {
        managedStatisticResource = new StatisticResourceJmxImpl(stat, this);
        managedStatisticResource.getStatistics();// inits timer
        managedStatisticsResourcesMap.put(stat, managedStatisticResource);
      }
    }
    return managedStatisticResource;
  }

  /**
   * Override createSystemMemberCache by instantiating SystemMemberCacheJmxImpl if it was not
   * created earlier.
   *
   * @param vm GemFireVM reference for which this JMX resource is to be created
   * @return SystemMemberCacheJmxImpl - JMX Implementation of SystemMemberCache
   * @throws AdminException if constructing SystemMemberCacheJmxImpl instance fails
   */
  @Override
  protected SystemMemberCache createSystemMemberCache(GemFireVM vm)
      throws org.apache.geode.admin.AdminException {
    if (managedSystemMemberCache == null) {
      managedSystemMemberCache = new SystemMemberCacheJmxImpl(vm);
    }
    return managedSystemMemberCache;
  }

  // -------------------------------------------------------------------------
  // Create MBean attributes for each ConfigurationParameter
  // -------------------------------------------------------------------------

  /**
   * Add MBean attribute definitions for each ConfigurationParameter.
   *
   * @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
   */
  @Override
  public ManagedBean addDynamicAttributes(ManagedBean managed)
      throws org.apache.geode.admin.AdminException {
    return Helper.addDynamicAttributes(this, managed);
  }

  /**
   * Cleans up Managed Resources created for the client that was connected to the server represented
   * by this class.
   *
   * @param clientId id of the client to be removed
   * @return List of ManagedResources associated with the client of given client id
   */
  /*
   * This clean up is for the clients. The clients are started with a loner DM. Hence the clientId
   * is not supposed to contain '/' as per InternalDistributedMember.toString().
   */
  public List<ManagedResource> cleanupBridgeClientResources(String clientId) {
    List<ManagedResource> returnedResources = new ArrayList<ManagedResource>();

    String compatibleId = "id_" + MBeanUtil.makeCompliantMBeanNameProperty(clientId);
    synchronized (this.managedStatisticsResourcesMap) {
      Set<Entry<StatResource, StatisticResourceJmxImpl>> entrySet =
          this.managedStatisticsResourcesMap.entrySet();

      for (Iterator<Entry<StatResource, StatisticResourceJmxImpl>> it = entrySet.iterator(); it
          .hasNext();) {
        Entry<StatResource, StatisticResourceJmxImpl> entry = it.next();
        StatisticResourceJmxImpl resource = entry.getValue();
        if (resource.getMBeanName().contains(compatibleId)) {
          it.remove(); // remove matching entry
          returnedResources.add(resource);
        }
      }
    }
    return returnedResources;
  }

  /**
   * Implementation handles client membership changes.
   *
   * @param clientId id of the client for whom membership change happened
   * @param eventType membership change type; one of {@link ClientMembershipMessage#JOINED},
   *        {@link ClientMembershipMessage#LEFT}, {@link ClientMembershipMessage#CRASHED}
   */
  @Override
  public void handleClientMembership(String clientId, int eventType) {
    String notifType = null;
    List<ManagedResource> cleanedUp = null;

    if (eventType == ClientMembershipMessage.LEFT) {
      notifType = NOTIF_CLIENT_LEFT;
      cleanedUp = cleanupBridgeClientResources(clientId);
    } else if (eventType == ClientMembershipMessage.CRASHED) {
      notifType = NOTIF_CLIENT_CRASHED;
      cleanedUp = cleanupBridgeClientResources(clientId);
    } else if (eventType == ClientMembershipMessage.JOINED) {
      notifType = NOTIF_CLIENT_JOINED;
    }

    if (cleanedUp != null) {
      for (ManagedResource resource : cleanedUp) {
        MBeanUtil.unregisterMBean(resource);
      }
    }

    Helper.sendNotification(this, new Notification(notifType, this.modelMBean,
        Helper.getNextNotificationSequenceNumber(), clientId));
  }

  /**
   * Implementation handles creation of cache by extracting the details from the given event object
   * and sending the {@link SystemMemberJmx#NOTIF_CACHE_CREATED} notification to the connected JMX
   * Clients.
   *
   * @param event event object corresponding to the creation of the cache
   */
  @Override
  public void handleCacheCreate(SystemMemberCacheEvent event) {
    Helper.sendNotification(this, new Notification(NOTIF_CACHE_CREATED, this.modelMBean,
        Helper.getNextNotificationSequenceNumber(), Helper.getCacheEventDetails(event)));
  }

  /**
   * Implementation handles closure of cache by extracting the details from the given event object
   * and sending the {@link SystemMemberJmx#NOTIF_CACHE_CLOSED} notification to the connected JMX
   * Clients.
   *
   * @param event event object corresponding to the closure of the cache
   */
  @Override
  public void handleCacheClose(SystemMemberCacheEvent event) {
    Helper.sendNotification(this, new Notification(NOTIF_CACHE_CLOSED, this.modelMBean,
        Helper.getNextNotificationSequenceNumber(), Helper.getCacheEventDetails(event)));
  }

  /**
   * Implementation handles creation of region by extracting the details from the given event object
   * and sending the {@link SystemMemberJmx#NOTIF_REGION_CREATED} notification to the connected JMX
   * Clients. Region Path is set as User Data in Notification.
   *
   * @param event event object corresponding to the creation of a region
   */
  @Override
  public void handleRegionCreate(SystemMemberRegionEvent event) {
    Notification notification = new Notification(NOTIF_REGION_CREATED, this.modelMBean,
        Helper.getNextNotificationSequenceNumber(), Helper.getRegionEventDetails(event));

    notification.setUserData(event.getRegionPath());

    Helper.sendNotification(this, notification);
  }

  /**
   * Implementation should handle loss of region by extracting the details from the given event
   * object and sending the {@link SystemMemberJmx#NOTIF_REGION_LOST} notification to the connected
   * JMX Clients. Region Path is set as User Data in Notification. Additionally, it also clears the
   * ManagedResources created for the region that is lost.
   *
   * @param event event object corresponding to the loss of a region
   */
  @Override
  public void handleRegionLoss(SystemMemberRegionEvent event) {
    SystemMemberCacheJmxImpl cacheResource = this.managedSystemMemberCache;

    if (cacheResource != null) {
      ManagedResource cleanedUp = cacheResource.cleanupRegionResources(event.getRegionPath());

      if (cleanedUp != null) {
        MBeanUtil.unregisterMBean(cleanedUp);
      }
    }

    Notification notification = new Notification(NOTIF_REGION_LOST, this.modelMBean,
        Helper.getNextNotificationSequenceNumber(), Helper.getRegionEventDetails(event));

    notification.setUserData(event.getRegionPath());

    Helper.sendNotification(this, notification);
  }
}
