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

#include "StatSamplerStats.hpp"

#include "StatisticsManager.hpp"

namespace apache {
namespace geode {
namespace statistics {

StatSamplerStats::StatSamplerStats(StatisticsFactory* statFactory) {
  statDescriptorArr = new StatisticDescriptor*[2];
  statDescriptorArr[0] = statFactory->createIntCounter(
      "sampleCount", "Total number of samples taken by this sampler.",
      "samples", false);

  statDescriptorArr[1] = statFactory->createLongCounter(
      "sampleTime", "Total amount of time spent taking samples.",
      "milliseconds", false);

  samplerType =
      statFactory->createType("StatSampler", "Stats on the statistic sampler.",
                              StatSamplerStats::statDescriptorArr, 2);
  sampleCountId = samplerType->nameToId("sampleCount");
  sampleTimeId = samplerType->nameToId("sampleTime");
  this->samplerStats = statFactory->createStatistics(samplerType, "statSampler",
                                                     statFactory->getId());
}

void StatSamplerStats::setInitialValues() {
  if (samplerStats) {
    samplerStats->setInt(sampleCountId, 0);
    samplerStats->setLong(sampleTimeId, 0);
  }
}

void StatSamplerStats::tookSample(int64_t nanosSpentWorking) {
  if (samplerStats) {
    samplerStats->incInt(sampleCountId, 1);
    samplerStats->incLong(sampleTimeId, nanosSpentWorking / 1000000);
  }
}

void StatSamplerStats::close() {
  if (samplerStats) {
    samplerStats->close();
  }
}

StatSamplerStats::~StatSamplerStats() {
  samplerType = nullptr;
  for (int32_t i = 0; i < 2; i++) {
    statDescriptorArr[i] = nullptr;
  }
  samplerStats = nullptr;
}

}  // namespace statistics
}  // namespace geode
}  // namespace apache
