/*
 * 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.concurrent.atomic.AtomicInteger;

import javax.management.MBeanException;
import javax.management.MalformedObjectNameException;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.RuntimeOperationsException;
import javax.naming.OperationNotSupportedException;

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

import org.apache.geode.SystemFailure;
import org.apache.geode.admin.AdminException;
import org.apache.geode.admin.ConfigurationParameter;
import org.apache.geode.admin.OperationCancelledException;
import org.apache.geode.admin.StatisticResource;
import org.apache.geode.admin.SystemMember;
import org.apache.geode.admin.SystemMemberCache;
import org.apache.geode.admin.SystemMemberCacheEvent;
import org.apache.geode.admin.SystemMemberRegionEvent;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.cache.Operation;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.internal.admin.ClientMembershipMessage;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * Defines methods that all <code>SystemMember</code> MBeans should implement.
 *
 * @since GemFire 4.0
 */
public interface SystemMemberJmx extends SystemMember, NotificationListener {
  /**
   * Notification type for indicating a cache got created on a member of this distributed system.
   */
  String NOTIF_CACHE_CREATED =
      DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.created";
  /**
   * Notification type for indicating a cache is closed on a member of this distributed system.
   */
  String NOTIF_CACHE_CLOSED = DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.closed";
  /**
   * Notification type for indicating a region is created in a cache on a member of this distributed
   * system.
   */
  String NOTIF_REGION_CREATED =
      DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.region.created";
  /**
   * Notification type for indicating a region was removed from a cache on a member of this
   * distributed system.
   */
  String NOTIF_REGION_LOST =
      DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.region.lost";

  /** Notification type for indicating client joined */
  String NOTIF_CLIENT_JOINED =
      DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.client.joined";

  /** Notification type for indicating client left */
  String NOTIF_CLIENT_LEFT =
      DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.client.left";

  /** Notification type for indicating client crashed */
  String NOTIF_CLIENT_CRASHED =
      DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.client.crashed";

  /**
   * Gets the interval in seconds between config refreshes
   *
   * @return the current refresh interval in seconds
   */
  int getRefreshInterval();

  /**
   * RefreshInterval is now set only through the AdminDistributedSystem property refreshInterval.
   * Attempt to set refreshInterval on SystemMemberJmx 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
   */
  @Deprecated
  void setRefreshInterval(int refreshInterval) throws OperationNotSupportedException;

  /**
   * Sets the refresh interval field. Sets interval in seconds between config refreshes; zero or
   * less turns off auto refreshing. Manual refreshing has no effect on when the next scheduled
   * refresh will occur.
   */
  void _setRefreshInterval(int refreshInterval);

  /**
   * Gets this member's cache.
   *
   * @return <code>ObjectName</code> for this member's cache
   *
   * @throws AdminException If this system member does not host a cache
   */
  ObjectName manageCache() throws AdminException, MalformedObjectNameException;

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

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

  /**
   * Handles notification to refresh. Reacts by refreshing the values of this GemFireManager's
   * ConfigurationParamaters. Any other notification is ignored.
   *
   * @param notification the JMX notification being received
   * @param hb handback object is unused
   */
  @Override
  void handleNotification(Notification notification, Object hb);

  /**
   * 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
   */
  ManagedBean addDynamicAttributes(ManagedBean managed) throws AdminException;


  /**
   * Implementation should handle creation of cache by extracting the details from the given event
   * object.
   *
   * @param event event object corresponding to the creation of the cache
   */
  void handleCacheCreate(SystemMemberCacheEvent event);

  /**
   * Implementation should handle closure of cache by extracting the details from the given event
   * object.
   *
   * @param event event object corresponding to the closure of the cache
   */
  void handleCacheClose(SystemMemberCacheEvent event);

  /**
   * Implementation should handle creation of region by extracting the details from the given event
   * object.
   *
   * @param event event object corresponding to the creation of a region
   */
  void handleRegionCreate(SystemMemberRegionEvent event);

  /**
   * Implementation should handle loss of region by extracting the details from the given event
   * object.
   *
   * @param event event object corresponding to the loss of a region
   */
  void handleRegionLoss(SystemMemberRegionEvent event);

  /**
   * Implementation should handle 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}
   */
  void handleClientMembership(String clientId, int eventType);

  ////////////////////// Inner Classess //////////////////////

  /**
   * A helper class that provides implementation of the <code>SystemMemberJmx</code> interface as
   * static methods.
   */
  class Helper {
    private static final Logger logger = LogService.getLogger();

    @MakeNotStatic
    private static final AtomicInteger notificationSequenceNumber = new AtomicInteger();

    public static int setAndReturnRefreshInterval(SystemMemberJmx member, int refreshInterval) {
      int ret = refreshInterval;

      try {
        MBeanUtil.registerRefreshNotification(member, // NotificationListener
            ((ManagedResource) member).getMBeanName(), // User Data
            RefreshNotificationType.SYSTEM_MEMBER_CONFIG, refreshInterval); // int

      } catch (RuntimeException e) {
        logger.warn(e.getMessage(), e); // dead in water, print, and then ignore
        ret = 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
        ret = 0; // zero out to avoid more exceptions
      }

      return ret;
    }

    public static ObjectName manageCache(SystemMemberJmx member)
        throws AdminException, MalformedObjectNameException {
      boolean IthrewIt = false;
      try {
        SystemMemberCache cache = member.getCache();
        if (cache == null) {
          IthrewIt = true;
          throw new AdminException(
              "This System Member does not have a Cache.");
        }
        SystemMemberCacheJmxImpl cacheJmx = (SystemMemberCacheJmxImpl) cache;
        return ObjectName.getInstance(cacheJmx.getMBeanName());
      } catch (AdminException e) {
        if (!IthrewIt) {
          logger.warn(e.getMessage(), e);
        }
        throw e;
      } catch (RuntimeException e) {
        logger.warn(e.getMessage(), e);
        throw e;
      } 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);
        throw e;
      }
    }

    public static ObjectName[] manageStats(SystemMemberJmx member)
        throws AdminException, MalformedObjectNameException {
      try {
        StatisticResource[] stats = member.getStats();
        ObjectName[] onames = new ObjectName[stats.length];
        for (int i = 0; i < stats.length; i++) {
          StatisticResourceJmxImpl stat = (StatisticResourceJmxImpl) stats[i];
          onames[i] = ObjectName.getInstance(stat.getMBeanName());
        }
        return onames;
      } catch (AdminException e) {
        logger.warn(e.getMessage(), e);
        throw e;
      } catch (RuntimeException e) {
        logger.warn(e.getMessage(), e);
        throw e;
      } 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);
        throw e;
      }
    }

    public static ObjectName[] manageStat(SystemMemberJmx member, String statisticsTypeName)
        throws AdminException, MalformedObjectNameException {
      try {
        StatisticResource[] stats = member.getStat(statisticsTypeName);
        if (stats == null)
          return null;
        else {
          ObjectName[] statNames = new ObjectName[stats.length];
          for (int i = 0; i < stats.length; i++) {
            StatisticResourceJmxImpl statJMX = (StatisticResourceJmxImpl) stats[i];
            statNames[i] = ObjectName.getInstance(statJMX.getMBeanName());
          }
          return statNames;
        }
      } catch (AdminException e) {
        logger.warn(e.getMessage(), e);
        throw e;
      } catch (RuntimeException e) {
        logger.warn(e.getMessage(), e);
        throw e;
      } catch (Error e) {
        logger.error(e.getMessage(), e);
        throw e;
      }
    }

    public static void handleNotification(SystemMemberJmx member, Notification notification,
        Object hb) {
      if (RefreshNotificationType.SYSTEM_MEMBER_CONFIG.getType().equals(notification.getType())
          && ((ManagedResource) member).getMBeanName().equals(notification.getUserData())) {

        try {
          member.refreshConfig();

        } catch (org.apache.geode.admin.AdminException e) {
          logger.warn(e.getMessage(), e);
        } catch (OperationCancelledException e) {
          // underlying resource is no longer reachable by remote admin
          logger.warn(e.getMessage(), e);
          member._setRefreshInterval(0);

        } catch (java.lang.RuntimeException e) {
          logger.warn(e.getMessage(), e); // dead in water, print, and then ignore
          member._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
          member._setRefreshInterval(0); // zero out to avoid more exceptions
        }
      }
    }

    public static ManagedBean addDynamicAttributes(SystemMemberJmx member, ManagedBean managed)
        throws AdminException {

      if (managed == null) {
        throw new IllegalArgumentException(
            "ManagedBean is null");
      }

      member.refreshConfig(); // to get the config parms...

      // need to create a new instance of ManagedBean to clean the "slate"...
      ManagedBean newManagedBean = new DynamicManagedBean(managed);
      ConfigurationParameter[] params = member.getConfiguration();
      for (int i = 0; i < params.length; i++) {
        ConfigurationParameterJmxImpl parm = (ConfigurationParameterJmxImpl) params[i];
        ConfigAttributeInfo attrInfo = new ConfigAttributeInfo(parm);

        attrInfo.setName(parm.getName());
        attrInfo.setDisplayName(parm.getName());
        attrInfo.setDescription(parm.getDescription());
        attrInfo.setType(parm.getJmxValueType().getName());

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

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

    /**
     * Returns the next notification sequence number.
     *
     * @return the notificationSequenceNumber
     */
    /* default */static int getNextNotificationSequenceNumber() {
      return notificationSequenceNumber.incrementAndGet();
    }

    /**
     * Returns the cache event details extracted from the given SystemMemberCacheEvent
     *
     * @param event SystemMemberCacheEvent instance
     * @return the cache event details extracted from the given SystemMemberCacheEvent
     */
    /* default */static String getCacheEventDetails(SystemMemberCacheEvent event) {
      String memberId = event.getMemberId();
      Operation operation = event.getOperation();

      return "CacheEvent[MemberId: " + memberId + ", operation: " + operation + "]";
    }

    /**
     * Returns the region event details extracted from the given SystemMemberRegionEvent
     *
     * @param event SystemMemberRegionEvent instance
     * @return the cache event details extracted from the given SystemMemberRegionEvent
     */
    /* default */static String getRegionEventDetails(SystemMemberRegionEvent event) {
      String memberId = event.getMemberId();
      Operation operation = event.getOperation();

      return "RegionEvent[MemberId: " + memberId + ", operation: " + operation + ", region:"
          + event.getRegionPath() + "]";
    }

    /**
     * Sends the given notification.
     *
     * @param notif notification to send
     *
     * @throws NullPointerException if resource or ModelMBean for resource is null
     */
    /* default */static void sendNotification(ManagedResource resource, Notification notif) {
      try {
        if (MBeanUtil.isRegistered(resource.getObjectName())) {
          resource.getModelMBean().sendNotification(notif);
          if (logger.isDebugEnabled()) {
            logger.debug("Sent '{}' notification", notif.getType());
          }
        }
      } catch (RuntimeOperationsException e) {
        logger
            .info(String.format("Failed to send %s notification for %s",
                new Object[] {"'" + notif.getType() + "'", "'" + notif.getMessage() + "'"}),
                e);
      } catch (MBeanException e) {
        logger
            .info(String.format("Failed to send %s notification for %s",
                new Object[] {"'" + notif.getType() + "'", "'" + notif.getMessage() + "'"}),
                e);
      }
    }
  }
}
