// Copyright 2016 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/network/net_log_logger.h"

#include <stdio.h>

#include <limits>
#include <string>

#include "base/bind.h"
#include "base/file_util.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_restrictions.h"
#include "base/time.h"
#include "base/values.h"
#include "cobalt/network/net_log_constants.h"

namespace cobalt {
namespace network {
namespace {
base::PlatformFile OpenFile(const FilePath& log_path) {
  int creation_flags =
      base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
  return base::CreatePlatformFile(log_path, creation_flags, NULL /* created */,
                                  NULL /* error */);
}

void AppendToFile(base::PlatformFile file, const std::string& data) {
  DCHECK_LE(data.size(), static_cast<size_t>(std::numeric_limits<int>::max()));
  int num_bytes_to_write = static_cast<int>(data.size());
  int bytes_written = base::WritePlatformFileAtCurrentPos(file, data.c_str(),
                                                          num_bytes_to_write);
  UNREFERENCED_PARAMETER(bytes_written);
  DLOG_IF(FATAL, bytes_written != num_bytes_to_write)
      << "Did not write all bytes to file.";
}

void CloseFile(base::PlatformFile file) {
  bool success = base::ClosePlatformFile(file);
  UNREFERENCED_PARAMETER(success);
  DLOG_IF(ERROR, !success) << "Failed to close file.";
}
}  // namespace

NetLogLogger::NetLogLogger(const FilePath& log_path)
    : log_writer_thread_("NetLogLogger IO"),
      log_file_(base::kInvalidPlatformFileValue) {
  if (!log_path.empty()) {
    base::ThreadRestrictions::ScopedAllowIO allow_io;
    log_file_ = OpenFile(log_path);
    if (log_file_ == base::kInvalidPlatformFileValue) {
      LOG(ERROR) << "Could not open file " << log_path.value()
                 << " for net logging";
      return;
    }

    const int kDefaultStackSize = 0;
    log_writer_thread_.StartWithOptions(
        base::Thread::Options(MessageLoop::TYPE_IO, kDefaultStackSize));

    // Write constants to the output file.  This allows loading files that have
    // different source and event types, as they may be added and removed
    // between Chrome versions.
    scoped_ptr<Value> value(NetLogConstants::GetConstants());
    std::string json;
    base::JSONWriter::Write(value.get(), &json);
    WriteToLog("{\"constants\": ");
    WriteToLog(json);
    WriteToLog(",\n");
    WriteToLog("\"events\": [\n");
  }
}

NetLogLogger::~NetLogLogger() {
  if (log_file_ != base::kInvalidPlatformFileValue) {
    log_writer_thread_.message_loop()->PostTask(
        FROM_HERE, base::Bind(&CloseFile, log_file_));
  }
  log_writer_thread_.Stop();
}

void NetLogLogger::StartObserving(net::NetLog* net_log) {
  net_log->AddThreadSafeObserver(this, net::NetLog::LOG_ALL_BUT_BYTES);
}

void NetLogLogger::OnAddEntry(const net::NetLog::Entry& entry) {
  scoped_ptr<Value> value(entry.ToValue());
  // Don't pretty print, so each JSON value occupies a single line, with no
  // breaks (Line breaks in any text field will be escaped).  Using strings
  // instead of integer identifiers allows logs from older versions to be
  // loaded, though a little extra parsing has to be done when loading a log.
  std::string json;
  base::JSONWriter::Write(value.get(), &json);
  if (log_file_ == base::kInvalidPlatformFileValue) {
    VLOG(1) << json;
  } else {
    WriteToLog(json);
    WriteToLog(",\n");
  }
}

void NetLogLogger::WriteToLog(const std::string& data) {
  DCHECK_NE(log_file_, base::kInvalidPlatformFileValue);
  DCHECK(log_writer_thread_.IsRunning());
  log_writer_thread_.message_loop()->PostTask(
      FROM_HERE, base::Bind(&AppendToFile, log_file_, data));
}

}  // namespace network
}  // namespace cobalt
