// Copyright 2016 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 <errno.h>
#include <stdio.h>
#include <sys/uio.h>
#include <threads.h>
#include <unistd.h>
#include <zircon/compiler.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/log.h>

// output via debuglog syscalls

static zx_handle_t log_handle;

#define LOGBUF_MAX (ZX_LOG_RECORD_MAX - sizeof(zx_log_record_t))

static mtx_t linebuffer_lock = MTX_INIT;
static char linebuffer[LOGBUF_MAX] __TA_GUARDED(linebuffer_lock);
static size_t linebuffer_size __TA_GUARDED(linebuffer_lock);

// Flushes and resets linebuffer.
static void flush_linebuffer_locked(void) __TA_REQUIRES(linebuffer_lock) {
  zx_debuglog_write(log_handle, 0, linebuffer, linebuffer_size);
  linebuffer_size = 0;
}

static void log_write(const void* data, size_t len) {
  mtx_lock(&linebuffer_lock);

  // printf calls write multiple times within a print, but each debuglog write
  // is a separate record, so each inserts a logical newline. To avoid
  // inappropriate breaking, do a version of _IOLBF here. A write of len == 0
  // indicates an fflush.

  if (len == 0) {
    flush_linebuffer_locked();
  }

  for (size_t i = 0; i < len; ++i) {
    if (linebuffer_size == sizeof(linebuffer)) {
      flush_linebuffer_locked();
    }
    char c = ((const char*)data)[i];
    linebuffer[linebuffer_size++] = c;
    if (c == '\n') {
      flush_linebuffer_locked();
    }
  }

  mtx_unlock(&linebuffer_lock);
}

// libc init and io stubs
// The reason these are here is that the "core" tests intentionally do not
// use fdio. See ./README.md.

static zx_handle_t root_resource;
static zx_handle_t mmio_root_resource;
static zx_handle_t system_root_resource;

__EXPORT
void __libc_extensions_init(uint32_t count, zx_handle_t handle[], uint32_t info[]) {
  for (unsigned n = 0; n < count; n++) {
    if (info[n] == PA_HND(PA_RESOURCE, 0)) {
      root_resource = handle[n];
      handle[n] = 0;
      info[n] = 0;
    }
    if (info[n] == PA_HND(PA_MMIO_RESOURCE, 0)) {
      mmio_root_resource = handle[n];
      handle[n] = 0;
      info[n] = 0;
    }
    if (info[n] == PA_HND(PA_SYSTEM_RESOURCE, 0)) {
      system_root_resource = handle[n];
      handle[n] = 0;
      info[n] = 0;
    }
  }
  if (root_resource == ZX_HANDLE_INVALID) {
    static const char kStandaloneMsg[] =
        "*** Standalone core-tests must run directly from userboot ***\n";
    zx_debug_write(kStandaloneMsg, sizeof(kStandaloneMsg) - 1);
    __builtin_trap();
  } else {
    if (zx_debuglog_create(root_resource, 0, &log_handle) != ZX_OK) {
      zx_process_exit(-2);
    }
    static const char kStartMsg[] = "*** Running standalone Zircon core tests ***\n";
    zx_debuglog_write(log_handle, 0, kStartMsg, sizeof(kStartMsg) - 1);
  }
}

__EXPORT
zx_handle_t get_root_resource(void) { return root_resource; }

__EXPORT
zx_handle_t get_mmio_root_resource(void) { return mmio_root_resource; }

__EXPORT
zx_handle_t get_system_root_resource(void) { return system_root_resource; }

__EXPORT
ssize_t write(int fd, const void* data, size_t count) {
  if ((fd == 1) || (fd == 2)) {
    log_write(data, count);
  }
  return count;
}

__EXPORT
ssize_t readv(int fd, const struct iovec* iov, int num) { return 0; }

__EXPORT
ssize_t writev(int fd, const struct iovec* iov, int num) {
  ssize_t count = 0;
  ssize_t r;
  while (num > 0) {
    if (iov->iov_len != 0) {
      r = write(fd, iov->iov_base, iov->iov_len);
      if (r < 0) {
        return count ? count : r;
      }
      if ((size_t)r < iov->iov_len) {
        return count + r;
      }
      count += r;
    }
    iov++;
    num--;
  }
  return count;
}

__EXPORT
off_t lseek(int fd, off_t offset, int whence) {
  errno = ENOSYS;
  return -1;
}

__EXPORT
int isatty(int fd) { return 1; }
