/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed 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.
 */

#define LOG_TAG "BtStopWatchLegacy"

#include "common/stop_watch_legacy.h"

#include <iomanip>
#include <mutex>
#include <sstream>
#include <utility>

#include <base/logging.h>
#include "osi/include/log.h"

namespace bluetooth {
namespace common {

static const int LOG_BUFFER_LENGTH = 10;
static std::array<StopWatchLog, LOG_BUFFER_LENGTH> stopwatch_logs;
static int current_buffer_index;
static std::recursive_mutex stopwatch_log_mutex;

void StopWatchLegacy::RecordLog(StopWatchLog log) {
  std::unique_lock<std::recursive_mutex> lock(stopwatch_log_mutex, std::defer_lock);
  if (!lock.try_lock()) {
    LOG_INFO("try_lock fail. log content: %s, took %zu us", log.message.c_str(),
             static_cast<size_t>(
                 std::chrono::duration_cast<std::chrono::microseconds>(
                     stopwatch_logs[current_buffer_index].end_timestamp -
                     stopwatch_logs[current_buffer_index].start_timestamp)
                     .count()));
    return;
  }
  if (current_buffer_index >= LOG_BUFFER_LENGTH) {
    current_buffer_index = 0;
  }
  stopwatch_logs[current_buffer_index] = std::move(log);
  current_buffer_index++;
  lock.unlock();
}

void StopWatchLegacy::DumpStopWatchLog() {
  std::lock_guard<std::recursive_mutex> lock(stopwatch_log_mutex);
  LOG_INFO("=-----------------------------------=");
  LOG_INFO("bluetooth stopwatch log history:");
  for (int i = 0; i < LOG_BUFFER_LENGTH; i++) {
    if (current_buffer_index >= LOG_BUFFER_LENGTH) {
      current_buffer_index = 0;
    }
    if (stopwatch_logs[current_buffer_index].message.empty()) {
      current_buffer_index++;
      continue;
    }
    std::stringstream ss;
    auto now = stopwatch_logs[current_buffer_index].timestamp;
    auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(
                      now.time_since_epoch()) %
                  1000;
    auto now_time_t = std::chrono::system_clock::to_time_t(now);
    ss << std::put_time(std::localtime(&now_time_t), "%Y-%m-%d %H:%M:%S");
    ss << '.' << std::setfill('0') << std::setw(3) << millis.count();
    std::string start_timestamp = ss.str();
    LOG_INFO("%s: %s: took %zu us", start_timestamp.c_str(),
             stopwatch_logs[current_buffer_index].message.c_str(),
             static_cast<size_t>(
                 std::chrono::duration_cast<std::chrono::microseconds>(
                     stopwatch_logs[current_buffer_index].end_timestamp -
                     stopwatch_logs[current_buffer_index].start_timestamp)
                     .count()));
    current_buffer_index++;
  }
  LOG_INFO("=-----------------------------------=");
}

StopWatchLegacy::StopWatchLegacy(std::string text)
    : text_(std::move(text)),
      timestamp_(std::chrono::system_clock::now()),
      start_timestamp_(std::chrono::high_resolution_clock::now()) {}

StopWatchLegacy::~StopWatchLegacy() {
  StopWatchLog sw_log;
  sw_log.timestamp = timestamp_;
  sw_log.start_timestamp = start_timestamp_;
  sw_log.end_timestamp = std::chrono::high_resolution_clock::now();
  sw_log.message = std::move(text_);

  RecordLog(std::move(sw_log));
}

}  // namespace common
}  // namespace bluetooth
