// Copyright 2015 The Chromium 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 "shell/tracer.h"

#include <stdio.h>
#include <string.h>

#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/trace_event/trace_event.h"

namespace shell {

Tracer::Tracer()
    : tracing_(false), first_chunk_written_(false), trace_file_(nullptr) {
}

Tracer::~Tracer() {
}

void Tracer::Start(const std::string& categories,
                   const std::string& duration_seconds_str,
                   const std::string& filename) {
  trace_duration_secs_ = 5;
  if (!duration_seconds_str.empty()) {
    CHECK(base::StringToInt(duration_seconds_str, &trace_duration_secs_))
        << "Could not parse --trace-startup-duration value "
        << duration_seconds_str;
  }
  tracing_ = true;
  trace_filename_ = filename;
  categories_ = categories;
  base::trace_event::CategoryFilter category_filter(categories);
  base::trace_event::TraceLog::GetInstance()->SetEnabled(
      category_filter, base::trace_event::TraceLog::RECORDING_MODE,
      base::trace_event::TraceOptions(base::trace_event::RECORD_UNTIL_FULL));
}

void Tracer::DidCreateMessageLoop() {
  if (!tracing_)
    return;

  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&shell::Tracer::StopAndFlushToFile, base::Unretained(this)),
      base::TimeDelta::FromSeconds(trace_duration_secs_));
}

void Tracer::StartCollectingFromTracingService(
    tracing::TraceCoordinatorPtr coordinator) {
  coordinator_ = coordinator.Pass();
  mojo::DataPipe data_pipe;
  coordinator_->Start(data_pipe.producer_handle.Pass(), categories_);
  drainer_.reset(new mojo::common::DataPipeDrainer(
      this, data_pipe.consumer_handle.Pass()));
}

void Tracer::StopAndFlushToFile() {
  if (tracing_)
    StopTracingAndFlushToDisk();
}

void Tracer::ConnectToController(
    mojo::InterfaceRequest<tracing::TraceController> request) {
  auto impl = new mojo::TraceControllerImpl(request.Pass());
  impl->set_tracing_already_started(tracing_);
}

void Tracer::StopTracingAndFlushToDisk() {
  tracing_ = false;
  trace_file_ = fopen(trace_filename_.c_str(), "w+");
  PCHECK(trace_file_);
  static const char kStart[] = "{\"traceEvents\":[";
  PCHECK(fwrite(kStart, 1, strlen(kStart), trace_file_) == strlen(kStart));

  // At this point we might be connected to the tracing service, in which case
  // we want to tell it to stop tracing and we will send the data we've
  // collected in process to it.
  if (coordinator_) {
    coordinator_->StopAndFlush();
  } else {
    // Or we might not be connected. If we aren't connected to the tracing
    // service we want to collect the tracing data gathered ourselves and flush
    // it to disk. We do this in a blocking fashion (for this thread) so we can
    // gather as much data as possible on shutdown.
    base::trace_event::TraceLog::GetInstance()->SetDisabled();
    {
      base::WaitableEvent flush_complete_event(false, false);
      // TraceLog::Flush requires a message loop but we've already shut ours
      // down.
      // Spin up a new thread to flush things out.
      base::Thread flush_thread("mojo_shell_trace_event_flush");
      flush_thread.Start();
      flush_thread.message_loop()->PostTask(
          FROM_HERE,
          base::Bind(&Tracer::EndTraceAndFlush, base::Unretained(this),
                     trace_filename_,
                     base::Bind(&base::WaitableEvent::Signal,
                                base::Unretained(&flush_complete_event))));
      base::trace_event::TraceLog::GetInstance()
          ->SetCurrentThreadBlocksMessageLoop();
      flush_complete_event.Wait();
    }
  }
}

void Tracer::WriteFooterAndClose() {
  static const char kEnd[] = "]}";
  PCHECK(fwrite(kEnd, 1, strlen(kEnd), trace_file_) == strlen(kEnd));
  PCHECK(fclose(trace_file_) == 0);
  trace_file_ = nullptr;
  LOG(INFO) << "Wrote trace data to " << trace_filename_;
}

void Tracer::EndTraceAndFlush(const std::string& filename,
                              const base::Closure& done_callback) {
  base::trace_event::TraceLog::GetInstance()->SetDisabled();
  base::trace_event::TraceLog::GetInstance()->Flush(base::Bind(
      &Tracer::WriteTraceDataCollected, base::Unretained(this), done_callback));
}

void Tracer::WriteTraceDataCollected(
    const base::Closure& done_callback,
    const scoped_refptr<base::RefCountedString>& events_str,
    bool has_more_events) {
  if (events_str->size()) {
    WriteCommaIfNeeded();

    PCHECK(fwrite(events_str->data().c_str(), 1, events_str->data().length(),
                  trace_file_) == events_str->data().length());
  }

  if (!has_more_events && !done_callback.is_null())
    done_callback.Run();
}

void Tracer::OnDataAvailable(const void* data, size_t num_bytes) {
  const char* chars = static_cast<const char*>(data);
  trace_service_data_.append(chars, num_bytes);
}

void Tracer::OnDataComplete() {
  if (!trace_service_data_.empty()) {
    WriteCommaIfNeeded();
    const char* const chars = trace_service_data_.data();
    size_t num_bytes = trace_service_data_.length();
    PCHECK(fwrite(chars, 1, num_bytes, trace_file_) == num_bytes);
    trace_service_data_ = std::string();
  }
  drainer_.reset();
  coordinator_.reset();
  WriteFooterAndClose();
}

void Tracer::WriteCommaIfNeeded() {
  if (first_chunk_written_)
    PCHECK(fwrite(",", 1, 1, trace_file_) == 1);
  first_chunk_written_ = true;
}

}  // namespace shell
