/*
 * 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.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.management.ObjectName;

import org.apache.logging.log4j.Logger;

import org.apache.geode.DataSerializable;
import org.apache.geode.DataSerializer;
import org.apache.geode.internal.DataSerializableFixedID;
import org.apache.geode.internal.Version;
import org.apache.geode.internal.logging.LogService;

/**
 * Central component for federation It consists of an Object State as well as some meta data for the
 * Object being federated.
 *
 *
 */

public class FederationComponent
    implements java.io.Serializable, DataSerializable, DataSerializableFixedID {
  private static final Logger logger = LogService.getLogger();

  private static final String THIS_COMPONENT = FederationComponent.class.getName();
  private static final long serialVersionUID = 3123549507449088591L;

  /**
   * Name of the MBean. This name will be replicated at Managing Node
   */
  private String objectName;

  /**
   * Name if the interface class . It will determine the interface for MBean at Managing Node side
   */
  private String interfaceClassName;

  /**
   * Flag to determine if MBean emits notification or not.
   */
  private boolean notificationEmitter;

  /**
   * This Map holds the object state as property-value Every component should be serializable
   */
  private Map<String, Object> objectState = new HashMap<String, Object>();

  private transient Map<String, Method> getterMethodMap;

  private transient Object mbeanObject;

  private transient Class mbeanInterfaceClass;


  private transient Map<String, Object> oldObjectState = new HashMap<String, Object>();

  private final transient Map<Method, OpenMethod> methodHandlerMap = OpenTypeUtil.newMap();

  private transient boolean prevRefreshChangeDetected = false;

  /**
   *
   * @param objectName ObjectName of the MBean
   * @param interfaceClass interface class of the MBean
   * @param notificationEmitter specifies whether this MBean is going to emit notifications
   */
  public FederationComponent(Object object, ObjectName objectName, Class interfaceClass,
      boolean notificationEmitter) {
    this.objectName = objectName.toString();
    this.interfaceClassName = interfaceClass.getCanonicalName();
    this.mbeanInterfaceClass = interfaceClass;
    this.notificationEmitter = notificationEmitter;
    this.mbeanObject = object;
    getterMethodMap = new HashMap<String, Method>();
    initGetters(interfaceClass);

  }

  public FederationComponent() {}

  // Introspect the mbeanInterface and initialize this object's maps.
  //
  private void initGetters(Class<?> mbeanInterface) {
    final Method[] methodArray = mbeanInterface.getMethods();

    for (Method m : methodArray) {
      String name = m.getName();

      String attrName = "";
      if (name.startsWith("get")) {
        attrName = name.substring(3);
      } else if (name.startsWith("is") && m.getReturnType() == boolean.class) {
        attrName = name.substring(2);
      }

      if (attrName.length() != 0 && m.getParameterTypes().length == 0
          && m.getReturnType() != void.class) { // For Getters
        m.setAccessible(true);
        getterMethodMap.put(attrName, m);
        methodHandlerMap.put(m, OpenMethod.from(m));
      }
    }
  }

  /**
   * gets the Canonical name of the MBean interface
   *
   * @return mbean interface class name
   */

  public String getMBeanInterfaceClass() {
    return interfaceClassName;
  }

  /**
   * True if this MBean is a notification emitter.
   *
   * @return whether its a notification emitter or not
   */

  public boolean isNotificationEmitter() {
    return notificationEmitter;
  }

  /**
   * This method will get called from Management Thread. This will dynamically invoke the MBeans
   * getter methods and set them in ObjectState Map.
   *
   * In Future releases we can implement the delta propagation here
   *
   * @return true if the refresh detects that the state changed. It will return false if two
   *         consecutive refresh calls results in no state change. This indicates to the
   *         LocalManager whether to send the MBean state to Manager or not.
   */

  public boolean refreshObjectState(boolean keepOldState) {
    boolean changeDetected = false;
    Object[] args = null;
    if (keepOldState) {
      oldObjectState.putAll(objectState);
    }
    for (Map.Entry<String, Method> gettorMethodEntry : getterMethodMap.entrySet()) {
      String property = gettorMethodEntry.getKey();
      Object propertyValue = null;

      try {
        Method m = gettorMethodEntry.getValue();
        propertyValue = m.invoke(mbeanObject, args);


        // To Handle open types in getter values
        OpenMethod op = methodHandlerMap.get(m);
        propertyValue = op.toOpenReturnValue(propertyValue);

      } catch (Exception e) {
        propertyValue = null;
        if (logger.isTraceEnabled()) {
          logger.trace(e.getMessage());
        }

      }

      Object oldValue = objectState.put(property, propertyValue);
      if (!changeDetected) {
        if (propertyValue != null) {
          if (!propertyValue.equals(oldValue)) {
            changeDetected = true;
          }
        } else { // new value is null
          if (oldValue != null) {
            changeDetected = true;
          }
        }
      }
    }
    boolean retVal = prevRefreshChangeDetected || changeDetected;
    prevRefreshChangeDetected = changeDetected;
    return retVal;
  }


  public boolean equals(Object anObject) {

    if (this == anObject) {
      return true;
    }
    if (anObject instanceof FederationComponent) {
      FederationComponent anotherFedComp = (FederationComponent) anObject;
      if (anotherFedComp.interfaceClassName.equals(this.interfaceClassName)
          && anotherFedComp.notificationEmitter == this.notificationEmitter
          && anotherFedComp.objectState.equals(this.objectState)
          && anotherFedComp.objectName.equals(this.objectName))
        return true;
    }

    return false;
  }


  public int hashCode() {
    return objectName.hashCode();
  }

  /**
   * Managing node will get Object state by calling this method
   *
   * @return value of the given property
   */
  public Object getValue(String propertyName) {
    return objectState.get(propertyName);
  }

  public String toString() {
    if (Boolean.getBoolean("debug.Management")) {
      return " ObjectName = " + objectName + ",InterfaceClassName = " + interfaceClassName
          + ", NotificationEmitter = " + notificationEmitter + ", ObjectState = "
          + objectState.toString();
    } else {
      return "ObjectName = " + objectName;
    }
  }

  public Map<String, Object> getObjectState() {
    return objectState;
  }

  public Map<String, Object> getOldState() {
    return oldObjectState;
  }


  @Override
  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
    this.notificationEmitter = DataSerializer.readPrimitiveBoolean(in);
    this.interfaceClassName = DataSerializer.readString(in);
    this.objectState = DataSerializer.readHashMap(in);
    this.objectName = DataSerializer.readString(in);
  }

  @Override
  public void toData(DataOutput out) throws IOException {

    DataSerializer.writePrimitiveBoolean(this.notificationEmitter, out);
    DataSerializer.writeString(this.interfaceClassName, out);
    DataSerializer.writeHashMap((HashMap<?, ?>) objectState, out);
    DataSerializer.writeString(this.objectName, out);
  }

  @Override
  public int getDSFID() {
    return DataSerializableFixedID.MGMT_FEDERATION_COMPONENT;
  }

  public Object getMBeanObject() {
    return mbeanObject;
  }

  public Class getInterfaceClass() {
    return mbeanInterfaceClass;
  }


  @Override
  public Version[] getSerializationVersions() {
    // TODO Auto-generated method stub
    return null;
  }


}
