/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/logging/rtc_event_log/rtc_event_log_helper_thread.h"

#include <algorithm>

#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/rtc_base/timeutils.h"

#ifdef ENABLE_RTC_EVENT_LOG

namespace webrtc {

namespace {
const int kEventsInHistory = 10000;

bool IsConfigEvent(const rtclog::Event& event) {
  rtclog::Event_EventType event_type = event.type();
  return event_type == rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT ||
         event_type == rtclog::Event::VIDEO_SENDER_CONFIG_EVENT ||
         event_type == rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT ||
         event_type == rtclog::Event::AUDIO_SENDER_CONFIG_EVENT;
}
}  // namespace

// RtcEventLogImpl member functions.
RtcEventLogHelperThread::RtcEventLogHelperThread(
    SwapQueue<ControlMessage>* message_queue,
    SwapQueue<std::unique_ptr<rtclog::Event>>* event_queue)
    : message_queue_(message_queue),
      event_queue_(event_queue),
      file_(FileWrapper::Create()),
      thread_(&ThreadOutputFunction, this, "RtcEventLog thread"),
      max_size_bytes_(std::numeric_limits<int64_t>::max()),
      written_bytes_(0),
      start_time_(0),
      stop_time_(std::numeric_limits<int64_t>::max()),
      has_recent_event_(false),
      wake_periodically_(false, false),
      wake_from_hibernation_(false, false),
      file_finished_(false, false) {
  RTC_DCHECK(message_queue_);
  RTC_DCHECK(event_queue_);
  thread_.Start();
}

RtcEventLogHelperThread::~RtcEventLogHelperThread() {
  ControlMessage message;
  message.message_type = ControlMessage::TERMINATE_THREAD;
  message.stop_time = rtc::TimeMicros();
  while (!message_queue_->Insert(&message)) {
    // We can't destroy the event log until we have stopped the thread,
    // so clear the message queue and try again. Note that if we clear
    // any STOP_FILE events, then the threads calling StopLogging would likely
    // wait indefinitely. However, there should not be any such calls as we
    // are executing the destructor.
    LOG(LS_WARNING) << "Clearing message queue to terminate thread.";
    message_queue_->Clear();
  }
  wake_from_hibernation_.Set();
  wake_periodically_.Set();  // Wake up the output thread.
  thread_.Stop();            // Wait for the thread to terminate.
}

void RtcEventLogHelperThread::WaitForFileFinished() {
  wake_from_hibernation_.Set();
  wake_periodically_.Set();
  file_finished_.Wait(rtc::Event::kForever);
}

void RtcEventLogHelperThread::SignalNewEvent() {
  wake_from_hibernation_.Set();
}

bool RtcEventLogHelperThread::AppendEventToString(rtclog::Event* event) {
  rtclog::EventStream event_stream;
  event_stream.add_stream();
  event_stream.mutable_stream(0)->Swap(event);
  // We create a new event stream per event but because of the way protobufs
  // are encoded, events can be merged by concatenating them. Therefore,
  // it will look like a single stream when we read it back from file.
  bool stop = true;
  if (written_bytes_ + static_cast<int64_t>(output_string_.size()) +
          event_stream.ByteSize() <=
      max_size_bytes_) {
    event_stream.AppendToString(&output_string_);
    stop = false;
  }
  // Swap the event back so that we don't mix event types in the queues.
  event_stream.mutable_stream(0)->Swap(event);
  return stop;
}

bool RtcEventLogHelperThread::LogToMemory() {
  RTC_DCHECK(!file_->is_open());
  bool message_received = false;

  // Process each event earlier than the current time and append it to the
  // appropriate history_.
  int64_t current_time = rtc::TimeMicros();
  if (!has_recent_event_) {
    has_recent_event_ = event_queue_->Remove(&most_recent_event_);
  }
  while (has_recent_event_ &&
         most_recent_event_->timestamp_us() <= current_time) {
    if (IsConfigEvent(*most_recent_event_)) {
      config_history_.push_back(std::move(most_recent_event_));
    } else {
      history_.push_back(std::move(most_recent_event_));
      if (history_.size() > kEventsInHistory)
        history_.pop_front();
    }
    has_recent_event_ = event_queue_->Remove(&most_recent_event_);
    message_received = true;
  }
  return message_received;
}

void RtcEventLogHelperThread::StartLogFile() {
  RTC_DCHECK(file_->is_open());
  bool stop = false;
  output_string_.clear();

  // Create and serialize the LOG_START event.
  rtclog::Event start_event;
  start_event.set_timestamp_us(start_time_);
  start_event.set_type(rtclog::Event::LOG_START);
  AppendEventToString(&start_event);

  // Serialize the config information for all old streams.
  for (auto& event : config_history_) {
    AppendEventToString(event.get());
  }

  // Serialize the events in the event queue.
  while (!history_.empty() && !stop) {
    stop = AppendEventToString(history_.front().get());
    if (!stop) {
      history_.pop_front();
    }
  }

  // Write to file.
  if (!file_->Write(output_string_.data(), output_string_.size())) {
    LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file.";
    // The current FileWrapper implementation closes the file on error.
    RTC_DCHECK(!file_->is_open());
    return;
  }
  written_bytes_ += output_string_.size();

  // Free the allocated memory since we probably won't need this amount of
  // space again.
  output_string_.clear();
  output_string_.shrink_to_fit();

  if (stop) {
    RTC_DCHECK(file_->is_open());
    StopLogFile();
  }
}

bool RtcEventLogHelperThread::LogToFile() {
  RTC_DCHECK(file_->is_open());
  output_string_.clear();
  bool message_received = false;

  // Append each event older than both the current time and the stop time
  // to the output_string_.
  int64_t current_time = rtc::TimeMicros();
  int64_t time_limit = std::min(current_time, stop_time_);
  if (!has_recent_event_) {
    has_recent_event_ = event_queue_->Remove(&most_recent_event_);
  }
  bool stop = false;
  while (!stop && has_recent_event_ &&
         most_recent_event_->timestamp_us() <= time_limit) {
    stop = AppendEventToString(most_recent_event_.get());
    if (!stop) {
      if (IsConfigEvent(*most_recent_event_)) {
        config_history_.push_back(std::move(most_recent_event_));
      }
      has_recent_event_ = event_queue_->Remove(&most_recent_event_);
    }
    message_received = true;
  }

  // Write string to file.
  if (!file_->Write(output_string_.data(), output_string_.size())) {
    LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file.";
    // The current FileWrapper implementation closes the file on error.
    RTC_DCHECK(!file_->is_open());
    return message_received;
  }
  written_bytes_ += output_string_.size();

  // We want to stop logging if we have reached the file size limit. We also
  // want to stop logging if the remaining events are more recent than the
  // time limit, or in other words if we have terminated the loop despite
  // having more events in the queue.
  if ((has_recent_event_ && most_recent_event_->timestamp_us() > stop_time_) ||
      stop) {
    RTC_DCHECK(file_->is_open());
    StopLogFile();
  }
  return message_received;
}

void RtcEventLogHelperThread::StopLogFile() {
  RTC_DCHECK(file_->is_open());
  output_string_.clear();

  rtclog::Event end_event;
  // This function can be called either because we have reached the stop time,
  // or because we have reached the log file size limit. Therefore, use the
  // current time if we have not reached the time limit.
  end_event.set_timestamp_us(
      std::min(stop_time_, rtc::TimeMicros()));
  end_event.set_type(rtclog::Event::LOG_END);
  AppendEventToString(&end_event);

  if (written_bytes_ + static_cast<int64_t>(output_string_.size()) <=
      max_size_bytes_) {
    if (!file_->Write(output_string_.data(), output_string_.size())) {
      LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file.";
      // The current FileWrapper implementation closes the file on error.
      RTC_DCHECK(!file_->is_open());
    }
    written_bytes_ += output_string_.size();
  }

  max_size_bytes_ = std::numeric_limits<int64_t>::max();
  written_bytes_ = 0;
  start_time_ = 0;
  stop_time_ = std::numeric_limits<int64_t>::max();
  output_string_.clear();
  file_->CloseFile();
  RTC_DCHECK(!file_->is_open());
}

void RtcEventLogHelperThread::ProcessEvents() {
  ControlMessage message;

  while (true) {
    bool message_received = false;
    // Process control messages.
    while (message_queue_->Remove(&message)) {
      switch (message.message_type) {
        case ControlMessage::START_FILE:
          if (!file_->is_open()) {
            max_size_bytes_ = message.max_size_bytes;
            start_time_ = message.start_time;
            stop_time_ = message.stop_time;
            file_.swap(message.file);
            StartLogFile();
          } else {
            // Already started. Ignore message and close file handle.
            message.file->CloseFile();
          }
          message_received = true;
          break;
        case ControlMessage::STOP_FILE:
          if (file_->is_open()) {
            stop_time_ = message.stop_time;
            LogToFile();  // Log remaining events from message queues.
          }
          // LogToFile might stop on it's own so we need to recheck the state.
          if (file_->is_open()) {
            StopLogFile();
          }
          file_finished_.Set();
          message_received = true;
          break;
        case ControlMessage::TERMINATE_THREAD:
          if (file_->is_open()) {
            StopLogFile();
          }
          return;
      }
    }

    // Write events to file or memory.
    if (file_->is_open()) {
      message_received |= LogToFile();
    } else {
      message_received |= LogToMemory();
    }

    // Accumulate a new batch of events instead of processing them one at a
    // time.
    if (message_received) {
      wake_periodically_.Wait(100);
    } else {
      wake_from_hibernation_.Wait(rtc::Event::kForever);
    }
  }
}

void RtcEventLogHelperThread::ThreadOutputFunction(void* obj) {
  RtcEventLogHelperThread* helper = static_cast<RtcEventLogHelperThread*>(obj);
  helper->ProcessEvents();
}

}  // namespace webrtc

#endif  // ENABLE_RTC_EVENT_LOG
