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

import org.apache.logging.log4j.Logger;

import org.apache.geode.logging.internal.log4j.api.LogService;

public class TestMemoryThresholdListener implements ResourceListener<MemoryEvent> {
  private static final Logger logger = LogService.getLogger();
  private int normalCalls = 0;
  private int criticalThresholdCalls = 0;
  private int evictionThresholdCalls = 0;
  private int evictionDisabledCalls = 0;
  private int criticalDisabledCalls = 0;
  private long bytesFromThreshold = 0;
  private int currentHeapPercentage = 0;
  private int allCalls = 0;
  private final boolean logOnEventCalls;

  public TestMemoryThresholdListener() {
    this(false);
  }

  public TestMemoryThresholdListener(boolean log) {
    this.logOnEventCalls = log;
  }

  public long getBytesFromThreshold() {
    synchronized (this) {
      return this.bytesFromThreshold;
    }
  }

  public int getCurrentHeapPercentage() {
    synchronized (this) {
      return this.currentHeapPercentage;
    }
  }

  public int getAllCalls() {
    synchronized (this) {
      return this.allCalls;
    }
  }

  public int getNormalCalls() {
    synchronized (this) {
      return this.normalCalls;
    }
  }

  public int getCriticalThresholdCalls() {
    synchronized (this) {
      return this.criticalThresholdCalls;
    }
  }

  public int getCriticalDisabledCalls() {
    synchronized (this) {
      return this.criticalDisabledCalls;
    }
  }

  public int getEvictionThresholdCalls() {
    synchronized (this) {
      return this.evictionThresholdCalls;
    }
  }

  public int getEvictionDisabledCalls() {
    synchronized (this) {
      return this.evictionDisabledCalls;
    }
  }

  public void resetThresholdCalls() {
    synchronized (this) {
      this.normalCalls = 0;
      this.criticalThresholdCalls = 0;
      this.evictionThresholdCalls = 0;
      this.bytesFromThreshold = 0;
      this.currentHeapPercentage = 0;
      this.evictionDisabledCalls = 0;
      this.criticalDisabledCalls = 0;
      this.allCalls = 0;
    }
  }

  @Override
  public String toString() {
    return new StringBuilder("TestListenerStatus:").append(" normalCalls :" + this.normalCalls)
        .append(" allCalls :" + this.allCalls)
        .append(" criticalThresholdCalls :" + this.criticalThresholdCalls)
        .append(" evictionThresholdCalls :" + this.evictionThresholdCalls)
        .append(" previousNormalCalls :" + this.normalCalls)
        .append(" bytesFromThreshold :" + this.bytesFromThreshold)
        .append(" currentHeapPercentage :" + this.currentHeapPercentage)
        .append(" evictionDisabledCalls :" + this.evictionDisabledCalls)
        .append(" criticalDisabledCalls :" + this.criticalDisabledCalls).toString();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.apache.geode.cache.control.ResourceListener#onEvent(java.lang.Object)
   */
  @Override
  public void onEvent(MemoryEvent event) {
    if (this.logOnEventCalls) {
      logger.info("TestMemoryThresholdListener onEvent " + event);
    }
    synchronized (this) {
      if (event.getState().isNormal()) {
        this.normalCalls++;
      }
      if (event.getState().isCritical() && event.getState() != event.getPreviousState()) {
        this.criticalThresholdCalls++;
      }
      if (event.getState().isEviction() && event.getState() != event.getPreviousState()) {
        this.evictionThresholdCalls++;
      }
      if (event.getState().isCriticalDisabled() && event.getState() != event.getPreviousState()) {
        this.criticalDisabledCalls++;
      }
      if (event.getState().isEvictionDisabled() && event.getState() != event.getPreviousState()) {
        this.evictionDisabledCalls++;
      }

      this.allCalls++;

      if (event.getState().isCritical()) {
        this.bytesFromThreshold =
            event.getBytesUsed() - event.getThresholds().getCriticalThresholdBytes();
      } else if (event.getState().isEviction()) {
        if (event.getPreviousState().isCritical()) {
          this.bytesFromThreshold =
              event.getThresholds().getCriticalThresholdBytes() - event.getBytesUsed();
        } else {
          this.bytesFromThreshold =
              event.getBytesUsed() - event.getThresholds().getEvictionThresholdBytes();
        }
      } else {
        this.bytesFromThreshold =
            event.getThresholds().getEvictionThresholdBytes() - event.getBytesUsed();
      }

      if (event.getThresholds().getMaxMemoryBytes() == 0) {
        this.currentHeapPercentage = 0;
      } else if (event.getBytesUsed() > event.getThresholds().getMaxMemoryBytes()) {
        this.currentHeapPercentage = 1;
      } else {
        this.currentHeapPercentage = convertToIntPercent(
            (double) event.getBytesUsed() / event.getThresholds().getMaxMemoryBytes());
      }
    }
  }

  /**
   * Convert a percentage as a double to an integer e.g. 0.09 => 9 also legal is 0.095 => 9
   *
   * @param percentHeap a percentage value expressed as a double e.g. 9.5% => 0.095
   * @return the calculated percent as an integer >= 0 and <= 100
   */
  private int convertToIntPercent(final double percentHeap) {
    assert percentHeap >= 0.0 && percentHeap <= 1.0;
    int ret = (int) Math.ceil(percentHeap * 100.0);
    assert ret >= 0 && ret <= 100;
    return ret;
  }
}
