// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/globals.h"
#if defined(DART_HOST_OS_FUCHSIA) && defined(SUPPORT_TIMELINE)
#include <lib/trace-engine/context.h>
#include <lib/trace-engine/instrumentation.h>
#include <zircon/syscalls.h>

#include "platform/utils.h"
#include "vm/object.h"
#include "vm/timeline.h"

namespace dart {

void TimelineEventFuchsiaRecorder::OnEvent(TimelineEvent* event) {
  if (event == nullptr) {
    return;
  }
  TimelineStream* stream = event->stream_;
  trace_string_ref_t category;
  trace_context_t* context = trace_acquire_context_for_category_cached(
      stream->fuchsia_name(), stream->trace_site(), &category);
  if (context == nullptr) {
    return;
  }

  trace_string_ref_t name;
  if (event->owns_label()) {
    // If the event owns the name, then the name will be deallocated, so
    // instruct the system trace to make a copy.
    name = trace_context_make_registered_string_copy(context, event->label(),
                                                     strlen(event->label()));
  } else {
    // If the event doesn't own the name, then it is a string literal, and
    // the system trace can use the pointer and not a copy.
    name =
        trace_context_make_registered_string_literal(context, event->label());
  }

  trace_thread_ref_t thread;
  trace_context_register_current_thread(context, &thread);

  trace_arg_t args[TRACE_MAX_ARGS];
  const intptr_t num_args = Utils::Minimum(
      event->arguments_length(), static_cast<intptr_t>(TRACE_MAX_ARGS));

  for (intptr_t i = 0; i < num_args; i++) {
    const char* name = event->arguments()[i].name;
    const char* value = event->arguments()[i].value;
    trace_string_ref_t arg_name =
        trace_context_make_registered_string_literal(context, name);
    trace_string_ref_t arg_value =
        trace_make_inline_string_ref(value, strlen(value));
    args[i] = trace_make_arg(arg_name, trace_make_string_arg_value(arg_value));
  }

  const uint64_t time_scale = zx_ticks_per_second() / kMicrosecondsPerSecond;
  const uint64_t start_time = event->LowTime() * time_scale;
  const uint64_t end_time = event->HighTime() * time_scale;

  // TODO(zra): The functions below emit Dart's timeline events all as category
  // "dart". Instead, we could have finer-grained categories that make use of
  // the name of the timeline stream, e.g. "VM", "GC", etc.
  switch (event->event_type()) {
    case TimelineEvent::kBegin:
      trace_context_write_duration_begin_event_record(
          context, start_time, &thread, &category, &name, args, num_args);
      break;
    case TimelineEvent::kEnd:
      trace_context_write_duration_end_event_record(
          context, start_time, &thread, &category, &name, args, num_args);
      break;
    case TimelineEvent::kInstant:
      trace_context_write_instant_event_record(
          context, start_time, &thread, &category, &name, TRACE_SCOPE_THREAD,
          args, num_args);
      break;
    case TimelineEvent::kAsyncBegin:
      trace_context_write_async_begin_event_record(context, start_time, &thread,
                                                   &category, &name,
                                                   event->Id(), args, num_args);
      break;
    case TimelineEvent::kAsyncEnd:
      trace_context_write_async_end_event_record(context, end_time, &thread,
                                                 &category, &name, event->Id(),
                                                 args, num_args);
      break;
    case TimelineEvent::kAsyncInstant:
      trace_context_write_async_instant_event_record(
          context, start_time, &thread, &category, &name, event->Id(), args,
          num_args);
      break;
    case TimelineEvent::kDuration:
      trace_context_write_duration_event_record(context, start_time, end_time,
                                                &thread, &category, &name, args,
                                                num_args);
      break;
    case TimelineEvent::kFlowBegin:
      trace_context_write_flow_begin_event_record(context, start_time, &thread,
                                                  &category, &name, event->Id(),
                                                  args, num_args);
      break;
    case TimelineEvent::kFlowStep:
      trace_context_write_flow_step_event_record(context, start_time, &thread,
                                                 &category, &name, event->Id(),
                                                 args, num_args);
      break;
    case TimelineEvent::kFlowEnd:
      trace_context_write_flow_end_event_record(context, start_time, &thread,
                                                &category, &name, event->Id(),
                                                args, num_args);
      break;
    default:
      // TODO(zra): Figure out what to do with kCounter and kMetadata.
      break;
  }
  trace_release_context(context);
}

}  // namespace dart

#endif  // defined(DART_HOST_OS_FUCHSIA) && defined(SUPPORT_TIMELINE)
