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

import java.util.Date;
import java.util.Map;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.logging.log4j.Logger;

import org.apache.geode.Statistics;
import org.apache.geode.StatisticsType;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.cache.CacheWriterException;
import org.apache.geode.cache.client.internal.PoolImpl;
import org.apache.geode.cache.client.internal.ServerRegionProxy;
import org.apache.geode.distributed.DistributedSystemDisconnectedException;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.internal.admin.remote.ClientHealthStats;
import org.apache.geode.internal.cache.EntryEventImpl;
import org.apache.geode.internal.cache.EventID;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.offheap.annotations.Released;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * This class publishes the client statistics using the admin region.
 */
public class ClientStatsManager {

  /**
   * Last cache that was initialized
   *
   * GuardedBy ClientStatsManager.class
   */
  @MakeNotStatic
  private static InternalCache lastInitializedCache = null;

  /**
   * GuardedBy ClientStatsManager.class
   */
  @MakeNotStatic
  private static Statistics cachePerfStats = null;

  /**
   * GuardedBy ClientStatsManager.class
   */
  @MakeNotStatic
  private static Statistics vmStats = null;

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

  /**
   * This method publishes the client stats using the admin region.
   *
   * @param pool Connection pool which may be used for admin region.
   */
  public static synchronized void publishClientStats(PoolImpl pool) {
    InternalCache currentCache = GemFireCacheImpl.getInstance();
    if (!initializeStatistics(currentCache)) {
      return; // handles null case too
    }
    if (logger.isDebugEnabled()) {
      logger.debug("Entering ClientStatsManager#publishClientStats...");
    }

    ClientHealthStats stats = getClientHealthStats(currentCache, pool);

    try {
      InternalDistributedSystem ds =
          (InternalDistributedSystem) currentCache.getDistributedSystem();
      ServerRegionProxy regionProxy =
          new ServerRegionProxy(ClientHealthMonitoringRegion.ADMIN_REGION_NAME, pool);

      boolean isOffHeap;
      if (ds.getOffHeapStore() != null) {
        isOffHeap = true;
      } else {
        isOffHeap = false;
      }
      EventID eventId = new EventID(ds);
      @Released
      EntryEventImpl event = new EntryEventImpl((Object) null, isOffHeap);
      try {
        event.setEventId(eventId);
        regionProxy.putForMetaRegion(ds.getDistributedMember(), stats, null, event, null);
      } finally {
        event.release();
      }
    } catch (DistributedSystemDisconnectedException e) {
      throw e;
    } catch (CacheWriterException cwx) {
      pool.getCancelCriterion().checkCancelInProgress(cwx);
      currentCache.getCancelCriterion().checkCancelInProgress(cwx);
      // TODO: Need to analyze these exception scenarios.
      logger.warn(
          "Failed to send client health stats to cacheserver.",
          cwx);
    } catch (Exception e) {
      pool.getCancelCriterion().checkCancelInProgress(e);
      currentCache.getCancelCriterion().checkCancelInProgress(e);
      logger.info("Failed to publish client statistics", e);
    }

    if (logger.isDebugEnabled()) {
      logger.debug("Exiting ClientStatsManager#publishClientStats.");
    }
  }

  public static void cleanupForTests() {
    lastInitializedCache = null;
  }

  /**
   * This method initializes the client statistics to be queried.
   *
   * GuardedBy ClientStatsManager.class
   *
   * @return true if statistics correctly initialized
   */
  private static boolean initializeStatistics(InternalCache currentCache) {
    if (currentCache == null) {
      return false;
    }

    InternalDistributedSystem ds = (InternalDistributedSystem) currentCache.getDistributedSystem();
    if (currentCache.isClosed()) {
      return false;
    }

    boolean restart = lastInitializedCache != currentCache;
    lastInitializedCache = currentCache;

    if (restart) {
      if (logger.isInfoEnabled()) {
        logger.info(
            "ClientStatsManager, intializing the statistics...");
      }
      cachePerfStats = null;
      vmStats = null;
    }

    if (cachePerfStats == null) {
      StatisticsType type = ds.findType("CachePerfStats");
      if (type != null) {
        Statistics[] statistics = ds.findStatisticsByType(type);
        if (statistics != null && statistics.length > 0) {
          cachePerfStats = statistics[0];
        }
      }
    }

    if (vmStats == null) {
      StatisticsType type = ds.findType("VMStats");
      if (type != null) {
        Statistics[] statistics = ds.findStatisticsByType(type);
        if (statistics != null && statistics.length > 0) {
          vmStats = statistics[0];
        }
      }
    }

    // Validate that cache has changed before logging the warning, thus logging it once per cache
    if (cachePerfStats == null && restart) {
      logger.warn(String.format("ClientStatsManager, %s are not available.",
          "CachePerfStats"));
    }

    // Validate that cache has changed before logging the warning, thus logging it once per cache
    if (vmStats == null && restart) {
      logger.warn(String.format("ClientStatsManager, %s are not available.",
          "VMStats"));
    }

    return true;
  }

  /**
   * This method queries the client stats & prepares the client health stats object to be published
   * to the server.
   *
   * @return the client health stats object to be published to the server.
   */
  private static ClientHealthStats getClientHealthStats(InternalCache currentCache, PoolImpl pool) {
    if (currentCache == null) {
      return null;
    }
    ClientHealthStats stats = new ClientHealthStats();

    long gets = -1;
    long puts = -1;
    long misses = -1;
    int cacheListenerCalls = -1;

    if (cachePerfStats != null) {
      gets = cachePerfStats.getLong("gets");
      puts = cachePerfStats.getLong("puts");
      misses = cachePerfStats.getLong("misses");
      cacheListenerCalls = cachePerfStats.getInt("cacheListenerCallsCompleted");
    }

    long processCpuTime = -1;
    int threads = -1;
    int cpus = -1;
    if (vmStats != null) {
      processCpuTime = vmStats.getLong("processCpuTime");
      threads = vmStats.getInt("threads");
      cpus = vmStats.getInt("cpus");
    }

    stats.setNumOfGets(gets);
    stats.setNumOfPuts(puts);
    stats.setNumOfMisses(misses);
    stats.setNumOfCacheListenerCalls(cacheListenerCalls);
    stats.setProcessCpuTime(processCpuTime);
    stats.setNumOfThreads(threads);
    stats.setCpus(cpus);

    String poolName = pool.getName();
    try {
      Map<String, String> newPoolStats = stats.getPoolStats();
      String poolStatsStr = "MinConnections=" + pool.getMinConnections() + ";MaxConnections="
          + pool.getMaxConnections() + ";Redundancy=" + pool.getSubscriptionRedundancy() + ";CQS="
          + pool.getQueryService().getCqs().length;
      logger.debug("ClientHealthStats for poolName " + poolName + " poolStatsStr=" + poolStatsStr);

      newPoolStats.put(poolName, poolStatsStr);

    } catch (Exception e) {
      logger.debug("Exception in getting pool stats in  getClientHealthStats "
          + ExceptionUtils.getStackTrace(e));
    }

    stats.setUpdateTime(new Date());
    return stats;
  }
}
