// Copyright 2015 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/trace_event/scoped_event_parser_trace.h"

#include "base/debug/trace_event_impl.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "cobalt/base/cobalt_paths.h"
#include "cobalt/trace_event/event_parser.h"
#include "cobalt/trace_event/json_file_outputter.h"

namespace cobalt {
namespace trace_event {

ScopedEventParserTrace::ScopedEventParserTrace(
    const EventParser::ScopedEventFlowEndCallback& flow_end_event_callback) {
  CommonInit(flow_end_event_callback);
}

ScopedEventParserTrace::ScopedEventParserTrace(
    const EventParser::ScopedEventFlowEndCallback& flow_end_event_callback,
    const FilePath& log_relative_output_path) {
  FilePath absolute_output_path;
  PathService::Get(cobalt::paths::DIR_COBALT_DEBUG_OUT, &absolute_output_path);
  absolute_output_path_ = absolute_output_path.Append(log_relative_output_path);

  CommonInit(flow_end_event_callback);
}

void ScopedEventParserTrace::CommonInit(
    const EventParser::ScopedEventFlowEndCallback& flow_end_event_callback) {
  flow_end_event_callback_ = flow_end_event_callback;

  DCHECK(!base::debug::TraceLog::GetInstance()->IsEnabled());
  base::debug::TraceLog::GetInstance()->SetEnabled(true);
}

ScopedEventParserTrace::~ScopedEventParserTrace() {
  base::debug::TraceLog* trace_log = base::debug::TraceLog::GetInstance();

  trace_log->SetEnabled(false);

  // Setup our raw TraceLog::TraceEvent callback.
  EventParser event_parser(flow_end_event_callback_);

  // Setup the JSON outputter callback if the client had provided a JSON
  // file output path.
  base::optional<JSONFileOutputter> json_outputter;
  base::debug::TraceLog::OutputCallback json_output_callback;
  if (absolute_output_path_) {
    json_outputter.emplace(*absolute_output_path_);
    if (json_outputter->GetError()) {
      DLOG(WARNING) << "Error opening JSON tracing output file for writing: "
                    << absolute_output_path_->value();
      json_outputter = base::nullopt;
    } else {
      json_output_callback =
          base::Bind(&JSONFileOutputter::OutputTraceData,
                     base::Unretained(&json_outputter.value()));
    }
  }

  // Flush the trace log through our callbacks.
  trace_log->FlushWithRawEvents(
      base::Bind(&EventParser::ParseEvent, base::Unretained(&event_parser)),
      json_output_callback);
}

namespace {
void EndEventParserTrace(scoped_ptr<ScopedEventParserTrace> trace,
                         base::Closure callback) {
  trace.reset();
  callback.Run();
}
}  // namespace

void TraceWithEventParserForDuration(
    const EventParser::ScopedEventFlowEndCallback& flow_end_event_callback,
    const base::Closure& flow_end_event_finish_callback,
    const base::TimeDelta& duration) {
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&EndEventParserTrace,
                 base::Passed(make_scoped_ptr(
                     new ScopedEventParserTrace(flow_end_event_callback))),
                 flow_end_event_finish_callback),
      duration);
}

bool IsTracing() { return base::debug::TraceLog::GetInstance()->IsEnabled(); }

}  // namespace trace_event
}  // namespace cobalt
