// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include "object/log_dispatcher.h"

#include <lib/counters.h>
#include <zircon/errors.h>
#include <zircon/rights.h>
#include <zircon/syscalls/log.h>

#include <fbl/alloc_checker.h>
#include <fbl/auto_lock.h>

KCOUNTER(dispatcher_log_create_count, "dispatcher.log.create")
KCOUNTER(dispatcher_log_destroy_count, "dispatcher.log.destroy")

zx_status_t LogDispatcher::Create(uint32_t flags, KernelHandle<LogDispatcher>* handle,
                                  zx_rights_t* rights) {
  fbl::AllocChecker ac;
  KernelHandle new_handle(fbl::AdoptRef(new (&ac) LogDispatcher(flags)));
  if (!ac.check())
    return ZX_ERR_NO_MEMORY;

  if (flags & ZX_LOG_FLAG_READABLE) {
    // Thread safety analysis is disabled here. Calling Initialize could
    // immediately call Notify, calling back into the dispatcher. Thus the lock
    // cannot be held. So far, the log dispatcher holding |reader_| has not
    // escaped beyond this thread, so it is safe to call Initialize.
    [&]() TA_NO_THREAD_SAFETY_ANALYSIS {
      new_handle.dispatcher()->reader_.Initialize(&LogDispatcher::Notify,
                                                  new_handle.dispatcher().get());
    }();
  }

  // Note: ZX_RIGHT_READ is added by sys_debuglog_create when ZX_LOG_FLAG_READABLE.
  *rights = default_rights();
  *handle = ktl::move(new_handle);
  return ZX_OK;
}

LogDispatcher::LogDispatcher(uint32_t flags) : SoloDispatcher(ZX_LOG_WRITABLE), flags_(flags) {
  kcounter_add(dispatcher_log_create_count, 1);
}

LogDispatcher::~LogDispatcher() {
  kcounter_add(dispatcher_log_destroy_count, 1);

  if (flags_ & ZX_LOG_FLAG_READABLE) {
    reader_.Disconnect();
  }
}

void LogDispatcher::Signal() {
  canary_.Assert();

  UpdateState(0, ZX_CHANNEL_READABLE);
}

// static
void LogDispatcher::Notify(void* cookie) {
  LogDispatcher* log = static_cast<LogDispatcher*>(cookie);
  log->Signal();
}

zx_status_t LogDispatcher::Write(uint32_t severity, uint32_t flags, ktl::string_view str) {
  canary_.Assert();

  return dlog_write(severity, flags_ | flags, str);
}

zx_status_t LogDispatcher::Read(uint32_t flags, dlog_record_t* record, size_t* actual) {
  canary_.Assert();

  if (!(flags_ & ZX_LOG_FLAG_READABLE))
    return ZX_ERR_BAD_STATE;

  Guard<Mutex> guard{get_lock()};

  zx_status_t status = reader_.Read(0, record, actual);
  if (status == ZX_ERR_SHOULD_WAIT) {
    UpdateStateLocked(ZX_CHANNEL_READABLE, 0);
  }

  return status;
}
