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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.management.ObjectName;

import org.apache.geode.management.LockServiceMXBean;
import org.apache.geode.management.internal.FederationComponent;
import org.apache.geode.management.internal.ManagementConstants;

/**
 * Bridge for the Distributed lock service. It provides an aggregated view of a lock service which
 * might be present in multiple members.
 *
 * Proxies are added as and when proxies are received by Federation framework.
 *
 * Each method which access all the proxies to gather data from them creates an Iterator. Iterates
 * over them and gather data. Creating multiple iterator on each method call is a concern and a
 * better way needs to be introduced.
 *
 *
 */
public class DistributedLockServiceBridge {

  /**
   * Map of LockServiceMXBean proxies
   */
  private Map<ObjectName, LockServiceMXBean> mapOfProxy;

  /**
   * List of locks. keeping it member level to avoid object creation cost during each call.
   */
  private List<String> listHeldLock;

  /**
   * Map of threads holding lock
   */
  private Map<String, String> threadsHoldingLock;

  /**
   * set size of this proxy set
   */
  private volatile int setSize;

  /**
   * Public constructor
   *
   * @param objectName name of the MBean
   * @param proxy reference to the proxy
   */
  public DistributedLockServiceBridge(ObjectName objectName, LockServiceMXBean proxy,
      FederationComponent newState) {
    this.mapOfProxy = new ConcurrentHashMap<ObjectName, LockServiceMXBean>();
    this.listHeldLock = new ArrayList<String>();
    this.threadsHoldingLock = new HashMap<String, String>();
    addProxyToMap(objectName, proxy);

  }

  /**
   * Add a proxy to the proxy map
   *
   * @param objectName name of the MBean
   * @param proxy reference to the proxy
   */
  public void addProxyToMap(ObjectName objectName, LockServiceMXBean proxy) {
    if (mapOfProxy != null) {
      mapOfProxy.put(objectName, proxy);
      setSize = mapOfProxy.values().size();
    }
  }

  /**
   *
   * @param objectName name of the MBean
   * @param proxy reference to the proxy
   * @return true if no proxies left for this aggregator to work on
   */
  public boolean removeProxyFromMap(ObjectName objectName, LockServiceMXBean proxy) {
    if (mapOfProxy != null) {
      mapOfProxy.remove(objectName);
      setSize = mapOfProxy.values().size();
      if (mapOfProxy.values().size() == 0) {
        setSize = 0;
        return true;

      }
    }
    return false;
  }



  /**
   *
   * @return member name of the grantor
   */
  public String fetchGrantorMember() {
    Iterator<LockServiceMXBean> it = mapOfProxy.values().iterator();
    if (it != null) {
      while (it.hasNext()) {
        String grantorMember = it.next().fetchGrantorMember();
        return grantorMember;
      }
    }
    return null;
  }

  /**
   *
   * @return number of members using this lock service
   */
  public int getMemberCount() {

    return setSize;
  }

  /**
   *
   * @return list of members using this lock service
   */
  public String[] getMemberNames() {
    Iterator<LockServiceMXBean> it = mapOfProxy.values().iterator();
    if (it != null) {
      while (it.hasNext()) {
        String[] memberNames = it.next().getMemberNames();
        return memberNames;
      }

    }
    return ManagementConstants.NO_DATA_STRING;
  }

  /**
   *
   * @return name of the lock service
   */
  public String getName() {
    Iterator<LockServiceMXBean> it = mapOfProxy.values().iterator();
    if (it != null) {
      while (it.hasNext()) {
        String name = it.next().getName();
        return name;
      }

    }
    return null;
  }

  /**
   *
   * @return lists the name of locks held by this member's threads
   */
  public String[] listHeldLocks() {
    Iterator<LockServiceMXBean> it = mapOfProxy.values().iterator();
    listHeldLock.clear();
    if (it != null) {
      while (it.hasNext()) {
        String[] locks = it.next().listHeldLocks();
        if (locks != null && locks.length > 0) {
          for (String lock : locks) {
            listHeldLock.add(lock);
          }
        }

      }

    }
    String[] tmpStr = new String[listHeldLock.size()];
    return listHeldLock.toArray(tmpStr);

  }

  /**
   *
   * @return a map of object name and thread name if this member holds lock or null/none
   */
  public Map<String, String> listThreadsHoldingLock() {
    Iterator<LockServiceMXBean> it = mapOfProxy.values().iterator();
    threadsHoldingLock.clear();
    if (it != null) {
      while (it.hasNext()) {
        Map<String, String> threadLockMap = it.next().listThreadsHoldingLock();
        if (threadLockMap != null) {
          threadsHoldingLock.putAll(threadLockMap);
        }


      }

    }
    return threadsHoldingLock;
  }

}
