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

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.logging.log4j.Logger;

import org.apache.geode.CancelCriterion;
import org.apache.geode.Statistics;
import org.apache.geode.SystemFailure;
import org.apache.geode.logging.internal.executors.LoggingExecutors;
import org.apache.geode.logging.internal.log4j.api.LogService;

public class CallbackSampler {
  private static final Logger logger = LogService.getLogger();
  private StatisticsManager statisticsManager;
  private final CancelCriterion cancelCriterion;
  private long sampleIntervalNanos;
  private ScheduledExecutorService executor;
  private final StatSamplerStats statSamplerStats;

  public CallbackSampler(final CancelCriterion cancelCriterion,
      final StatSamplerStats statSamplerStats) {
    this.cancelCriterion = cancelCriterion;
    this.statSamplerStats = statSamplerStats;
  }

  public void start(StatisticsManager statisticsManager, int sampleInterval, TimeUnit timeUnit) {
    ScheduledExecutorService executor =
        LoggingExecutors.newSingleThreadScheduledExecutor("CallbackSampler");
    start(executor, statisticsManager, sampleInterval, timeUnit);
  }

  void start(ScheduledExecutorService executor, StatisticsManager statisticsManager,
      int sampleInterval, TimeUnit timeUnit) {
    stop();
    this.statisticsManager = statisticsManager;
    this.executor = executor;

    executor.scheduleAtFixedRate(() -> sampleCallbacks(), sampleInterval, sampleInterval, timeUnit);
  }

  private void sampleCallbacks() {
    if (cancelCriterion.isCancelInProgress()) {
      executor.shutdown();
    }
    int errors = 0;
    int suppliers = 0;
    long start = System.nanoTime();
    try {
      for (Statistics stats : statisticsManager.getStatsList()) {
        StatisticsImpl statistics = (StatisticsImpl) stats;
        errors += statistics.updateSuppliedValues();
        suppliers += statistics.getSupplierCount();
      }
    } catch (VirtualMachineError e) {
      SystemFailure.initiateFailure(e);
    } catch (Throwable throwable) {
      logger.error("Error invoking statistic suppliers", throwable);
    } finally {
      long end = System.nanoTime();
      statSamplerStats.incSampleCallbackDuration(TimeUnit.NANOSECONDS.toMillis(end - start));
      statSamplerStats.incSampleCallbackErrors(errors);
      statSamplerStats.setSampleCallbacks(suppliers);
    }

  }

  public void stop() {
    if (executor != null) {
      this.executor.shutdown();
    }
  }
}
