// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// 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.

#include "cobalt/browser/memory_tracker/tool/buffered_file_writer.h"

#include "base/basictypes.h"
#include "base/logging.h"

#include "starboard/condition_variable.h"
#include "starboard/file.h"
#include "starboard/log.h"
#include "starboard/mutex.h"
#include "starboard/thread.h"
#include "starboard/types.h"

namespace cobalt {
namespace browser {
namespace memory_tracker {

BufferedFileWriter::BufferedFileWriter(const std::string& file_path)
    : current_log_buffer_(0),
      log_buffer_to_flush_(NULL),
      log_file_(kSbFileInvalid),
      diskwrite_mutex_(),
      diskwrite_cond_(diskwrite_mutex_),
      quit_thread_(false),
      file_path_(file_path) {
  SbMemorySet(log_buffers_, 0, sizeof(log_buffers_));
  StartThread();
}

BufferedFileWriter::~BufferedFileWriter() { QuitThread(); }

void BufferedFileWriter::QuitThread() {
  quit_thread_ = true;
  SwapBuffers();
  diskwrite_cond_.Signal();

  SbThreadJoin(flush_thread_, NULL);

  SbFileClose(log_file_);
  log_file_ = kSbFileInvalid;
}

void BufferedFileWriter::StartThread() {
  // Do not reset the LogBuffers here, as they may have been written to
  // before the log thread was started.
  int flags = kSbFileCreateAlways | kSbFileWrite;
  bool created_ok = false;
  SbFileError error_code = kSbFileOk;

  log_file_ = SbFileOpen(file_path_.c_str(), flags, &created_ok, &error_code);

  if (log_file_ == kSbFileInvalid || !created_ok) {
    SbLogRaw("Error creating memory log file\n");
    return;
  }

  flush_thread_ = SbThreadCreate(0,  // default stack size.
                                 kSbThreadPriorityHigh, kSbThreadNoAffinity,
                                 true,  // true - joinable.
                                 "AllocationLoggerWriter", ThreadEntryFunc,
                                 static_cast<void*>(this));
}

void BufferedFileWriter::Append(const char* data, size_t num_bytes) {
  if (num_bytes > kBufferSize) {
    // We can never log this, and it's probably an error, but let's not write
    // over the end of the buffer.
    DCHECK(false) << "Log data is larger than the full buffer size. "
                     "Dropping log data\n";
    return;
  }

  starboard::ScopedLock lock(buffer_write_mutex_);

  // This function may be called before memory_log_writer_start.
  if (log_buffers_[current_log_buffer_].num_bytes + num_bytes > kBufferSize) {
    if (!SwapBuffers()) {
      // Failed to swap the buffer, so we will have to drop this log
      DCHECK(false) << "Dropping log data. Try increasing buffer size.";
      return;
    }
  }

  LogBuffer& current_buffer = log_buffers_[current_log_buffer_];
  SbMemoryCopy(current_buffer.buffer + current_buffer.num_bytes, data,
               num_bytes);
  current_buffer.num_bytes += num_bytes;
  return;
}

void BufferedFileWriter::Run() {
  starboard::ScopedLock lock(diskwrite_mutex_);
  while (!quit_thread_) {
    if (log_buffer_to_flush_ != NULL) {
      size_t bytes_written =
          SbFileWrite(log_file_, log_buffer_to_flush_->buffer,
                      static_cast<int>(log_buffer_to_flush_->num_bytes));
      if (bytes_written != log_buffer_to_flush_->num_bytes) {
        SbLogRaw("Error writing to memory log. Aborting logging\n");
        break;
      }
      log_buffer_to_flush_->num_bytes = 0;
      log_buffer_to_flush_ = NULL;
    }
    diskwrite_cond_.Wait();  // Unlocks diskwrite_mutex_.
  }
}

void* BufferedFileWriter::ThreadEntryFunc(void* context) {
  BufferedFileWriter* self = static_cast<BufferedFileWriter*>(context);
  self->Run();
  return NULL;
}

bool BufferedFileWriter::SwapBuffers() {
  // If the non-logging threads block on this for too long, try increasing
  // the size of the buffers.
  diskwrite_mutex_.Acquire();

  bool can_swap = (log_buffer_to_flush_ == NULL);
  if (!can_swap) {
    SbLogRaw("Cannot swap buffer while a flush is pending.\n");
  } else {
    log_buffer_to_flush_ = &(log_buffers_[current_log_buffer_]);
    current_log_buffer_ = (current_log_buffer_ + 1) % kNumBuffers;
    SB_DCHECK(log_buffers_[current_log_buffer_].num_bytes == 0);
  }

  diskwrite_cond_.Signal();

  diskwrite_mutex_.Release();
  SbThreadYield();

  return can_swap;
}

}  // namespace memory_tracker
}  // namespace browser
}  // namespace cobalt
