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

import java.io.Serializable;

import javax.management.Attribute;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer;
import javax.management.ObjectName;

import org.apache.logging.log4j.Logger;

import org.apache.geode.cache.execute.FunctionContext;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.cache.execute.InternalFunction;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * A generic function to act as a conduit between Managing Node and Managed nodes.
 *
 * The direction of request flow is from Managing Node to Managing Node.
 *
 * The following methods are executed at Managed node on behalf of the proxy.
 *
 * 1) All setter methods 2) All operations 3) addNotificationListener 4) removeNotificationListener
 * 5) getNotificationInfo
 */
public class ManagementFunction implements InternalFunction {

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

  private static final long serialVersionUID = 1L;

  /**
   * Platform MBean server.
   */
  private MBeanServer mbeanServer = MBeanJMXAdapter.mbeanServer;

  /**
   * Notification hub instance
   */
  private NotificationHub notificationHub;

  /**
   * Public constructor
   *
   */
  public ManagementFunction(NotificationHub notifHub) {
    this.notificationHub = notifHub;
  }

  /**
   * Actual function execution. It delegates task at managed node according to the request received.
   *
   * If any exception is encountered it will set the result to UNDEFINED
   */
  @Override
  public void execute(FunctionContext fc) {

    boolean executedSuccessfully = false;

    InternalCache cache = ((InternalCache) fc.getCache()).getCacheForProcessingClientRequests();

    Object[] functionArguments = (Object[]) fc.getArguments();

    ObjectName objectName = (ObjectName) functionArguments[0];

    String methodName = (String) functionArguments[1];

    String[] signature = (String[]) functionArguments[2];

    Object[] args = (Object[]) functionArguments[3];
    String memberName = (String) functionArguments[4];

    Object returnObj = null;

    try {

      final int nargs = (args == null) ? 0 : args.length;

      if (methodName.startsWith("set") && methodName.length() > 3 && nargs == 1) {

        Attribute attr = new Attribute(methodName.substring(3), args[0]);
        mbeanServer.setAttribute(objectName, attr);
        fc.getResultSender().lastResult((Serializable) null);

      } else if (methodName.equals("addNotificationListener")) {
        notificationHub.addHubNotificationListener(memberName, objectName);
        fc.getResultSender().lastResult((Serializable) ManagementConstants.UNDEFINED);

      } else if (methodName.equals("removeNotificationListener")) {
        notificationHub.removeHubNotificationListener(memberName, objectName);
        fc.getResultSender().lastResult((Serializable) ManagementConstants.UNDEFINED);

      } else if (methodName.equals("getNotificationInfo")) {
        fc.getResultSender().lastResult(mbeanServer.getMBeanInfo(objectName));

      } else {
        returnObj = mbeanServer.invoke(objectName, methodName, args, signature);
        fc.getResultSender().lastResult((Serializable) returnObj);
      }

      executedSuccessfully = true;

    } catch (InstanceNotFoundException e) {
      if (cache != null && !cache.isClosed()) {
        sendException(e, fc);
      }
    } catch (Exception e) {
      sendException(e, fc);
    } finally {
      if (!executedSuccessfully) {
        if (cache == null || cache.isClosed()) {
          Exception e =
              new Exception("Member Is Shutting down");
          sendException(e, fc);
          return; // member is closing or invalid member
        }
      }
    }
  }

  @Override
  public String getId() {
    return ManagementConstants.MGMT_FUNCTION_ID;
  }

  private void sendException(Exception e, FunctionContext fc) {
    if (logger.isDebugEnabled()) {
      logger.debug("Management Function Could Not Be Executed", e);
    }
    fc.getResultSender().sendException(e);
  }

}
