// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shill/net/event_history.h"

#include <time.h>

#include <deque>

#include <base/logging.h>

#include "shill/net/shill_time.h"

using std::deque;

namespace shill {

void EventHistory::RecordEvent() {
  RecordEventInternal(time_->GetNow());
}

void EventHistory::ExpireEventsBefore(int seconds_ago, ClockType clock_type) {
  ExpireEventsBeforeInternal(seconds_ago, time_->GetNow(), clock_type);
}

void EventHistory::RecordEventAndExpireEventsBefore(int seconds_ago,
                                                    ClockType clock_type) {
  Timestamp now = time_->GetNow();
  RecordEventInternal(now);
  ExpireEventsBeforeInternal(seconds_ago, now, clock_type);
}

std::vector<std::string> EventHistory::ExtractWallClockToStrings() const {
  std::vector<std::string> strings;
  for (deque<Timestamp>::const_iterator it = events_.begin();
       it != events_.end(); ++it) {
    strings.push_back(it->wall_clock);
  }
  return strings;
}

void EventHistory::RecordEventInternal(Timestamp now) {
  events_.push_back(now);
  while (!events_.empty() && max_events_specified_ &&
         (events_.size() > static_cast<size_t>(max_events_saved_))) {
    events_.pop_front();
  }
}

void EventHistory::ExpireEventsBeforeInternal(int seconds_ago,
                                              Timestamp now,
                                              ClockType clock_type) {
  struct timeval interval = (const struct timeval){seconds_ago};
  while (!events_.empty()) {
    struct timeval elapsed = {0, 0};
    switch (clock_type) {
      case kClockTypeBoottime:
        timersub(&now.boottime, &events_.front().boottime, &elapsed);
        break;
      case kClockTypeMonotonic:
        timersub(&now.monotonic, &events_.front().monotonic, &elapsed);
        break;
      default: {
        NOTIMPLEMENTED()
            << __func__ << ": "
            << "Invalid clock type specified - defaulting to boottime clock";
        timersub(&now.boottime, &events_.front().boottime, &elapsed);
      }
    }
    if (timercmp(&elapsed, &interval, <)) {
      break;
    }
    events_.pop_front();
  }
}

int EventHistory::CountEventsWithinInterval(int seconds_ago,
                                            ClockType clock_type) {
  int num_events_in_interval = 0;
  Timestamp now = time_->GetNow();
  struct timeval interval = (const struct timeval){seconds_ago};
  int i = 0;
  for (const auto& event : events_) {
    struct timeval elapsed = {0, 0};
    switch (clock_type) {
      case kClockTypeBoottime:
        timersub(&now.boottime, &event.boottime, &elapsed);
        break;
      case kClockTypeMonotonic:
        timersub(&now.monotonic, &event.monotonic, &elapsed);
        break;
      default: {
        NOTIMPLEMENTED()
            << __func__ << ": "
            << "Invalid clock type specified - defaulting to boottime clock";
        timersub(&now.boottime, &event.boottime, &elapsed);
      }
    }
    if (timercmp(&elapsed, &interval, <=)) {
      num_events_in_interval = events_.size() - i;
      break;
    }
    ++i;
  }
  return num_events_in_interval;
}

}  // namespace shill
