// Copyright 2017 The Fuchsia 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 <lib/trace/observer.h>
#include <zircon/assert.h>

#include <utility>

namespace trace {

TraceObserver::TraceObserver() {}

TraceObserver::~TraceObserver() { Stop(); }

void TraceObserver::Start(async_dispatcher_t* dispatcher, fit::closure callback) {
  ZX_DEBUG_ASSERT(dispatcher);
  ZX_DEBUG_ASSERT(callback);

  Stop();
  callback_ = std::move(callback);

  zx_status_t status = zx::event::create(0u, &event_);
  ZX_ASSERT(status == ZX_OK);
  trace_register_observer(event_.get());

  wait_.set_object(event_.get());
  wait_.set_trigger(ZX_EVENT_SIGNALED);
  BeginWait(dispatcher);
}

void TraceObserver::Stop() {
  wait_.Cancel();
  callback_ = nullptr;

  if (event_) {
    trace_unregister_observer(event_.get());
    event_.reset();
  }
}

void TraceObserver::Handle(async_dispatcher_t* dispatcher, async::WaitBase* wait,
                           zx_status_t status, const zx_packet_signal_t* signal) {
  if (status != ZX_OK) {
    Stop();
    return;
  }

  ZX_DEBUG_ASSERT(status == ZX_OK);
  ZX_DEBUG_ASSERT(signal->observed & ZX_EVENT_SIGNALED);

  // Clear the signal otherwise we'll keep getting called.
  // Clear the signal *before* invoking the callback because there's no
  // synchronization between the engine and the observers, thus it's possible
  // that an observer could get back to back notifications.
  event_.signal(ZX_EVENT_SIGNALED, 0u);

  // Invoke the callback.
  callback_();

  // Tell engine we're done.
  trace_notify_observer_updated(event_.get());

  // Wait again!
  BeginWait(dispatcher);
}

void TraceObserver::BeginWait(async_dispatcher_t* dispatcher) {
  zx_status_t status = wait_.Begin(dispatcher);
  if (status != ZX_OK)
    Stop();
}

}  // namespace trace
