// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "uartdpi.h"

#ifdef __linux__
#include <pty.h>
#elif __APPLE__
#include <util.h>
#endif

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void *uartdpi_create(const char *name, const char *log_file_path) {
  struct uartdpi_ctx *ctx =
      (struct uartdpi_ctx *)malloc(sizeof(struct uartdpi_ctx));
  assert(ctx);

  int rv;

  // Initialize UART pseudo-terminal
  struct termios tty;
  cfmakeraw(&tty);

  rv = openpty(&ctx->host, &ctx->device, 0, &tty, 0);
  assert(rv != -1);

  rv = ttyname_r(ctx->device, ctx->ptyname, 64);
  assert(rv == 0 && "ttyname_r failed");

  int cur_flags = fcntl(ctx->host, F_GETFL, 0);
  assert(cur_flags != -1 && "Unable to read current flags.");
  int new_flags = fcntl(ctx->host, F_SETFL, cur_flags | O_NONBLOCK);
  assert(new_flags != -1 && "Unable to set FD flags");

  printf(
      "\n"
      "UART: Created %s for %s. Connect to it with any terminal program, e.g.\n"
      "$ screen %s\n",
      ctx->ptyname, name, ctx->ptyname);

  // Open log file (if requested)
  ctx->log_file = NULL;
  bool write_log_file = strlen(log_file_path) != 0;
  if (write_log_file) {
    if (strcmp(log_file_path, "-") == 0) {
      ctx->log_file = stdout;
      printf("UART: Additionally writing all UART output to STDOUT.\n");

    } else {
      FILE *log_file;
      log_file = fopen(log_file_path, "w");
      if (!log_file) {
        fprintf(stderr, "UART: Unable to open log file at %s: %s\n",
                log_file_path, strerror(errno));
      } else {
        ctx->log_file = log_file;
        printf("UART: Additionally writing all UART output to '%s'.\n",
               log_file_path);
      }
    }
  }

  return (void *)ctx;
}

void uartdpi_close(void *ctx_void) {
  struct uartdpi_ctx *ctx = (struct uartdpi_ctx *)ctx_void;
  if (!ctx) {
    return;
  }

  close(ctx->host);
  close(ctx->device);

  if (ctx->log_file) {
    // Always ensure the log file is flushed (most important when writing
    // to STDOUT)
    fflush(ctx->log_file);
    if (ctx->log_file != stdout) {
      fclose(ctx->log_file);
    }
  }

  free(ctx);
}

int uartdpi_can_read(void *ctx_void) {
  struct uartdpi_ctx *ctx = (struct uartdpi_ctx *)ctx_void;

  int rv = read(ctx->host, &ctx->tmp_read, 1);
  return (rv == 1);
}

char uartdpi_read(void *ctx_void) {
  struct uartdpi_ctx *ctx = (struct uartdpi_ctx *)ctx_void;

  return ctx->tmp_read;
}

void uartdpi_write(void *ctx_void, char c) {
  int rv;

  struct uartdpi_ctx *ctx = (struct uartdpi_ctx *)ctx_void;

  rv = write(ctx->host, &c, 1);
  assert(rv == 1 && "Write to pseudo-terminal failed.");

  if (ctx->log_file) {
    rv = fwrite(&c, sizeof(char), 1, ctx->log_file);
    assert(rv == 1 && "Write to log file failed.");
  }
}
