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

#include "sw/device/lib/runtime/print.h"

#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#include "sw/device/lib/base/macros.h"
#include "sw/device/lib/base/memory.h"
#include "sw/device/lib/base/status.h"

// This is declared as an enum to force the values to be
// compile-time constants, but the type is otherwise not
// used for anything.
enum {
  // Standard format specifiers.
  kPercent = '%',
  kCharacter = 'c',
  kString = 's',
  kSignedDec1 = 'd',
  kSignedDec2 = 'i',
  kUnsignedOct = 'o',
  kUnsignedHexLow = 'x',
  kUnsignedHexHigh = 'X',
  kUnsignedDec = 'u',
  kPointer = 'p',

  // Verilog-style format specifiers.
  kSvBinary = 'b',
  kSvHexLow = 'h',
  kSvHexHigh = 'H',

  // Other non-standard specifiers.
  kHexLeLow = 'y',
  kHexLeHigh = 'Y',
  kStatusResult = 'r',
};

// NOTE: all of the lengths of the strings below are given so that the NUL
// terminator is left off; that way, `sizeof(kConst)` does not include it.
static const char kDigitsLow[16] = "0123456789abcdef";
static const char kDigitsHigh[16] = "0123456789ABCDEF";

static const char kErrorNul[17] = "%<unexpected nul>";
static const char kUnknownSpec[15] = "%<unknown spec>";
static const char kErrorTooWide[12] = "%<bad width>";

static size_t base_dev_null(void *data, const char *buf, size_t len) {
  return len;
}
static buffer_sink_t base_stdout = {
    .data = NULL,
    // Note: Using `&base_dev_null` causes this variable to be placed in the
    // .data section and triggers the assertion in rom.ld.
    .sink = NULL,
};

void base_set_stdout(buffer_sink_t out) {
  if (out.sink == NULL) {
    out.sink = &base_dev_null;
  }
  base_stdout = out;
}

static size_t base_dev_uart(void *data, const char *buf, size_t len) {
  const dif_uart_t *uart = (const dif_uart_t *)data;
  for (size_t i = 0; i < len; ++i) {
    if (dif_uart_byte_send_polled(uart, (uint8_t)buf[i]) != kDifOk) {
      return i;
    }
  }
  return len;
}

void base_uart_stdout(const dif_uart_t *uart) {
  base_set_stdout(
      (buffer_sink_t){.data = (void *)uart, .sink = &base_dev_uart});
}

size_t base_printf(const char *format, ...) {
  va_list args;
  va_start(args, format);
  size_t bytes_left = base_vprintf(format, args);
  va_end(args);
  return bytes_left;
}

size_t base_vprintf(const char *format, va_list args) {
  return base_vfprintf(base_stdout, format, args);
}

typedef struct snprintf_captures_t {
  char *buf;
  size_t bytes_left;
} snprintf_captures_t;

static size_t snprintf_sink(void *data, const char *buf, size_t len) {
  snprintf_captures_t *captures = (snprintf_captures_t *)data;
  if (captures->bytes_left == 0) {
    return 0;
  }

  if (len > captures->bytes_left) {
    len = captures->bytes_left;
  }
  memcpy(captures->buf, buf, len);
  captures->buf += len;
  captures->bytes_left -= len;
  return len;
}

size_t base_snprintf(char *buf, size_t len, const char *format, ...) {
  va_list args;
  va_start(args, format);

  snprintf_captures_t data = {
      .buf = buf,
      .bytes_left = len,
  };
  buffer_sink_t out = {
      .data = &data,
      .sink = &snprintf_sink,
  };
  size_t bytes_left = base_vfprintf(out, format, args);
  va_end(args);
  return bytes_left;
}

size_t base_fprintf(buffer_sink_t out, const char *format, ...) {
  va_list args;
  va_start(args, format);
  size_t bytes_left = base_vfprintf(out, format, args);
  va_end(args);
  return bytes_left;
}

/**
 * Consumes characters from `format` until a '%' or NUL is reached. All
 * characters seen before that are then sinked into `out`.
 *
 * @param out the sink to write bytes to.
 * @param format a pointer to the format string to consume a prefix of.
 * @param[out] bytes_written out param for the number of bytes writen to `out`.
 * @return true if an unprocessed '%' was found.
 */
static bool consume_until_percent(buffer_sink_t out, const char **format,
                                  size_t *bytes_written) {
  size_t text_len = 0;
  while (true) {
    char c = (*format)[text_len];
    if (c == '\0' || c == kPercent) {
      if (text_len > 0) {
        *bytes_written += out.sink(out.data, *format, text_len);
      }
      *format += text_len;
      return c != '\0';
    }
    ++text_len;
  }
}

/**
 * Represents a parsed format specifier.
 */
typedef struct format_specifier {
  char type;
  size_t width;
  char padding;
  bool is_nonstd;
} format_specifier_t;

/**
 * Consumes characters from `format` until a complete format specifier is
 * parsed. See the documentation in `print.h` for full syntax.
 *
 * @param out the sink to write bytes to.
 * @param format a pointer to the format string to consume a prefix of.
 * @param[out] spec out param for the specifier.
 * @return whether the parse succeeded.
 */
static bool consume_format_specifier(buffer_sink_t out, const char **format,
                                     size_t *bytes_written,
                                     format_specifier_t *spec) {
  *spec = (format_specifier_t){0};

  // Consume the percent sign.
  ++(*format);

  // Parse a ! to detect an OpenTitan-specific extension (that isn't one
  // of the Verilog ones...).
  if ((*format)[0] == '!') {
    spec->is_nonstd = true;
    ++(*format);
  }

  // Attempt to parse out an unsigned, decimal number, a "width",
  // after the percent sign; the format specifier is the character
  // immediately after this width.
  //
  // `spec->padding` is used to indicate whether we've seen a width;
  // if nonzero, we have an actual width.
  size_t spec_len = 0;
  while (true) {
    char c = (*format)[spec_len];
    if (c == '\0') {
      *bytes_written += out.sink(out.data, kErrorNul, sizeof(kErrorNul));
      return false;
    }
    if (c < '0' || c > '9') {
      break;
    }
    if (spec->padding == 0) {
      if (c == '0') {
        spec->padding = '0';
        ++spec_len;
        continue;
      }
      spec->padding = ' ';
    }
    spec->width *= 10;
    spec->width += (c - '0');
    ++spec_len;
  }

  if ((spec->width == 0 && spec->padding != 0) || spec->width > 32) {
    *bytes_written += out.sink(out.data, kErrorTooWide, sizeof(kErrorTooWide));
    return false;
  }

  spec->type = (*format)[spec_len];
  *format += spec_len + 1;
  return true;
}

/**
 * Write the digits of `value` onto `out`.
 *
 * @param out the sink to write bytes to.
 * @param value the value to "stringify".
 * @param width the minimum width to print; going below will result in writing
 *        out zeroes.
 * @param base the base to express `value` in.
 * @param glyphs an array of characters to use as the digits of a number, which
 *        should be at least ast long as `base`.
 * @return the number of bytes written.
 */
static size_t write_digits(buffer_sink_t out, uint32_t value, uint32_t width,
                           char padding, uint32_t base, const char *glyphs) {
  // All allocations are done relative to a buffer that could hold the longest
  // textual representation of a number: ~0x0 in base 2, i.e., 32 ones.
  static const int kWordBits = sizeof(uint32_t) * 8;
  char buffer[kWordBits];

  size_t len = 0;
  if (value == 0) {
    buffer[kWordBits - 1] = glyphs[0];
    ++len;
  }
  while (value > 0) {
    uint32_t digit = value % base;
    value /= base;
    buffer[kWordBits - 1 - len] = glyphs[digit];
    ++len;
  }
  width = width == 0 ? 1 : width;
  width = width > kWordBits ? kWordBits : width;
  while (len < width) {
    buffer[kWordBits - len - 1] = padding;
    ++len;
  }
  return out.sink(out.data, buffer + (kWordBits - len), len);
}

static size_t write_status(buffer_sink_t out, status_t value, bool as_json) {
  // The module id is defined to be 3 chars long.
  char mod[] = {'"', 0, 0, 0, '"', ','};
  int32_t arg;
  const char *start;
  bool err = status_extract(value, &start, &arg, &mod[1]);

  // strlen of the status code.
  const char *end = start;
  while (*end)
    end++;
  size_t len = 0;

  len += out.sink(out.data, "{\"", as_json ? 2 : 0);
  len += out.sink(out.data, start, end - start);
  len += out.sink(out.data, "\"", as_json ? 1 : 0);

  // print the module id and arg.
  len += out.sink(out.data, ":[", 2);
  if (err) {
    // All error codes include the module identifier.
    len += out.sink(out.data, mod, sizeof(mod));
  }
  len += write_digits(out, arg, 0, 0, 10, kDigitsLow);
  len += out.sink(out.data, "]", 1);
  len += out.sink(out.data, "}", as_json ? 1 : 0);
  return len;
}

/**
 * Hexdumps `bytes` onto `out`.
 *
 * @param out the sink to write bytes to.
 * @param bytes the bytes to dump.
 * @param len the number of bytes to dump.
 * @param width the minimum width to print; going below will result in writing
 *        out zeroes.
 * @param padding the character to use for padding.
 * @param big_endian whether to print in big-endian order (i.e. as %x would).
 * @param glyphs an array of characters to use as the digits of a number, which
 *        should be at least ast long as `base`.
 * @return the number of bytes written.
 */
static size_t hex_dump(buffer_sink_t out, const char *bytes, size_t len,
                       uint32_t width, char padding, bool big_endian,
                       const char *glyphs) {
  size_t bytes_written = 0;
  char buf[32];
  size_t buffered = 0;
  if (len < width) {
    width -= len;
    memset(buf, padding, sizeof(buf));
    while (width > 0) {
      size_t to_write = width > ARRAYSIZE(buf) ? 32 : width;
      bytes_written += out.sink(out.data, buf, to_write);
      width -= to_write;
    }
  }

  for (size_t i = 0; i < len; ++i) {
    size_t idx = big_endian ? len - i - 1 : i;
    buf[buffered] = glyphs[(bytes[idx] >> 4) & 0xf];
    buf[buffered + 1] = glyphs[bytes[idx] & 0xf];
    buffered += 2;

    if (buffered == ARRAYSIZE(buf)) {
      bytes_written += out.sink(out.data, buf, buffered);
      buffered = 0;
    }
  }

  if (buffered != 0) {
    bytes_written += out.sink(out.data, buf, buffered);
  }
  return bytes_written;
}

/**
 * Prints out the next entry in `args` according to `spec`.
 *
 * This function assumes that `spec` accurately describes the next entry in
 * `args`.
 *
 * @param out the sink to write bytes to.
 * @param spec the specifier to use for stringifying.
 * @param[out] bytes_written out param for the number of bytes writen to `out`.
 * @param args the list to pull an entry from.
 */
static void process_specifier(buffer_sink_t out, format_specifier_t spec,
                              size_t *bytes_written, va_list *args) {
  // Switch on the specifier. At this point, we assert that there is
  // an initialized value of correct type in the VA list; if it is
  // missing, the caller has caused UB.
  switch (spec.type) {
    case kPercent: {
      if (spec.is_nonstd) {
        goto bad_spec;
      }
      *bytes_written += out.sink(out.data, "%", 1);
      break;
    }
    case kCharacter: {
      if (spec.is_nonstd) {
        goto bad_spec;
      }
      char value = (char)va_arg(*args, uint32_t);
      *bytes_written += out.sink(out.data, &value, 1);
      break;
    }
    case kString: {
      size_t len = 0;
      if (spec.is_nonstd) {
        // This implements %!s.
        len = va_arg(*args, size_t);
      }

      char *value = va_arg(*args, char *);
      while (!spec.is_nonstd && value[len] != '\0') {
        // This implements %s.
        ++len;
      }

      *bytes_written += out.sink(out.data, value, len);
      break;
    }
    case kSignedDec1:
    case kSignedDec2: {
      if (spec.is_nonstd) {
        goto bad_spec;
      }
      uint32_t value = va_arg(*args, uint32_t);
      if (((int32_t)value) < 0) {
        *bytes_written += out.sink(out.data, "-", 1);
        value = -value;
      }
      *bytes_written +=
          write_digits(out, value, spec.width, spec.padding, 10, kDigitsLow);
      break;
    }
    case kUnsignedOct: {
      if (spec.is_nonstd) {
        goto bad_spec;
      }
      uint32_t value = va_arg(*args, uint32_t);
      *bytes_written +=
          write_digits(out, value, spec.width, spec.padding, 8, kDigitsLow);
      break;
    }
    case kPointer: {
      if (spec.is_nonstd) {
        goto bad_spec;
      }
      // Pointers are formatted as 0x<hex digits>, where the width is always
      // set to the number necessary to represent a pointer on the current
      // platform, that is, the size of uintptr_t in nybbles. For example, on
      // different architecutres the null pointer prints as
      // - rv32imc: 0x00000000 (four bytes, eight nybbles).
      // - amd64:   0x0000000000000000 (eight bytes, sixteen nybbles).
      *bytes_written += out.sink(out.data, "0x", 2);
      uintptr_t value = va_arg(*args, uintptr_t);
      *bytes_written +=
          write_digits(out, value, sizeof(uintptr_t) * 2, '0', 16, kDigitsLow);
      break;
    }
    case kUnsignedHexLow:
      if (spec.is_nonstd) {
        size_t len = va_arg(*args, size_t);
        char *value = va_arg(*args, char *);
        *bytes_written += hex_dump(out, value, len, spec.width, spec.padding,
                                   /*big_endian=*/true, kDigitsLow);
        break;
      }
      OT_FALLTHROUGH_INTENDED;
    case kSvHexLow: {
      uint32_t value = va_arg(*args, uint32_t);
      *bytes_written +=
          write_digits(out, value, spec.width, spec.padding, 16, kDigitsLow);
      break;
    }
    case kUnsignedHexHigh:
      if (spec.is_nonstd) {
        size_t len = va_arg(*args, size_t);
        char *value = va_arg(*args, char *);
        *bytes_written += hex_dump(out, value, len, spec.width, spec.padding,
                                   /*big_endian=*/true, kDigitsHigh);
        break;
      }
      OT_FALLTHROUGH_INTENDED;
    case kSvHexHigh: {
      uint32_t value = va_arg(*args, uint32_t);
      *bytes_written +=
          write_digits(out, value, spec.width, spec.padding, 16, kDigitsHigh);
      break;
    }
    case kHexLeLow: {
      if (!spec.is_nonstd) {
        goto bad_spec;
      }
      size_t len = va_arg(*args, size_t);
      char *value = va_arg(*args, char *);
      *bytes_written += hex_dump(out, value, len, spec.width, spec.padding,
                                 /*big_endian=*/false, kDigitsLow);
      break;
    }
    case kHexLeHigh: {
      if (!spec.is_nonstd) {
        goto bad_spec;
      }
      size_t len = va_arg(*args, size_t);
      char *value = va_arg(*args, char *);
      *bytes_written += hex_dump(out, value, len, spec.width, spec.padding,
                                 /*big_endian=*/false, kDigitsHigh);
      break;
    }
    case kUnsignedDec: {
      if (spec.is_nonstd) {
        goto bad_spec;
      }
      uint32_t value = va_arg(*args, uint32_t);
      *bytes_written +=
          write_digits(out, value, spec.width, spec.padding, 10, kDigitsLow);
      break;
    }
    case kSvBinary: {
      if (spec.is_nonstd) {
        // Bools passed into a ... function will be automatically promoted
        // to int; va_arg(..., bool) is actually UB!
        if (va_arg(*args, int) != 0) {
          *bytes_written += out.sink(out.data, "true", 4);
        } else {
          *bytes_written += out.sink(out.data, "false", 5);
        }
        break;
      }
      uint32_t value = va_arg(*args, uint32_t);
      *bytes_written +=
          write_digits(out, value, spec.width, spec.padding, 2, kDigitsLow);
      break;
    }
    case kStatusResult: {
      status_t value = va_arg(*args, status_t);
      *bytes_written += write_status(out, value, spec.is_nonstd);
      break;
    }
    bad_spec:  // Used with `goto` to bail out early.
    default: {
      *bytes_written += out.sink(out.data, kUnknownSpec, sizeof(kUnknownSpec));
    }
  }
}

size_t base_vfprintf(buffer_sink_t out, const char *format, va_list args) {
  if (out.sink == NULL) {
    out.sink = &base_dev_null;
  }

  // NOTE: This copy is necessary on amd64 and other platforms, where
  // `va_list` is a fixed array type (and, as such, decays to a pointer in
  // an argument list). On PSABI RV32IMC, however, `va_list` is a `void*`, so
  // this is a copy of the pointer, not the array.
  va_list args_copy;
  va_copy(args_copy, args);

  size_t bytes_written = 0;
  while (format[0] != '\0') {
    if (!consume_until_percent(out, &format, &bytes_written)) {
      break;
    }
    format_specifier_t spec;
    if (!consume_format_specifier(out, &format, &bytes_written, &spec)) {
      break;
    }

    process_specifier(out, spec, &bytes_written, &args_copy);
  }

  va_end(args_copy);
  return bytes_written;
}

const char kBaseHexdumpDefaultFmtAlphabet[256] =
    // clang-format off
  // First 32 characters are not printable.
  "................................"
  // Printable ASCII.
  " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
  // The rest of the range is also not printable (129 characters).
  "................................................................"
  "................................................................"
  ".";
// clang-format on

static const base_hexdump_fmt_t kBaseHexdumpDefaultFmt = {
    .bytes_per_word = 2,
    .words_per_line = 8,
    .alphabet = &kBaseHexdumpDefaultFmtAlphabet,
};

size_t base_hexdump(const char *buf, size_t len) {
  return base_hexdump_with(kBaseHexdumpDefaultFmt, buf, len);
}

size_t base_snhexdump(char *out, size_t out_len, const char *buf, size_t len) {
  return base_snhexdump_with(out, out_len, kBaseHexdumpDefaultFmt, buf, len);
}

size_t base_fhexdump(buffer_sink_t out, const char *buf, size_t len) {
  return base_fhexdump_with(out, kBaseHexdumpDefaultFmt, buf, len);
}

size_t base_hexdump_with(base_hexdump_fmt_t fmt, const char *buf, size_t len) {
  return base_fhexdump_with(base_stdout, fmt, buf, len);
}

size_t base_snhexdump_with(char *out, size_t out_len, base_hexdump_fmt_t fmt,
                           const char *buf, size_t len) {
  snprintf_captures_t data = {
      .buf = out,
      .bytes_left = out_len,
  };
  buffer_sink_t sink = {
      .data = &data,
      .sink = &snprintf_sink,
  };
  return base_fhexdump_with(sink, fmt, buf, len);
}

size_t base_fhexdump_with(buffer_sink_t out, base_hexdump_fmt_t fmt,
                          const char *buf, size_t len) {
  size_t bytes_written = 0;
  size_t bytes_per_line = fmt.bytes_per_word * fmt.words_per_line;

  for (size_t line = 0; line < len; line += bytes_per_line) {
    bytes_written += base_fprintf(out, "%08x:", line);

    size_t chars_per_line = bytes_per_line * 2 + fmt.words_per_line;
    size_t line_bytes_written = 0;
    for (size_t word = 0; word < bytes_per_line; word += fmt.bytes_per_word) {
      if (len < line + word) {
        char spaces[16] = "                ";
        while (line_bytes_written < chars_per_line) {
          size_t to_print = chars_per_line - line_bytes_written;
          if (to_print > sizeof(spaces)) {
            to_print = sizeof(spaces);
          }
          line_bytes_written += base_fprintf(out, "%!s", to_print, spaces);
        }
        break;
      }

      size_t bytes_left = len - line - word;
      if (bytes_left > fmt.bytes_per_word) {
        bytes_left = fmt.bytes_per_word;
      }
      line_bytes_written += base_fprintf(out, " ");
      line_bytes_written +=
          hex_dump(out, buf + line + word, bytes_left, bytes_left, '0',
                   /*big_endian=*/false, kDigitsLow);
    }
    bytes_written += line_bytes_written;

    bytes_written += base_fprintf(out, "  ");
    size_t buffered = 0;
    char glyph_buffer[16];
    for (size_t byte = 0; byte < bytes_per_line; ++byte) {
      if (buffered == sizeof(glyph_buffer)) {
        bytes_written += base_fprintf(out, "%!s", buffered, glyph_buffer);
        buffered = 0;
      }
      if (line + byte >= len) {
        break;
      }
      glyph_buffer[buffered++] =
          (*fmt.alphabet)[(size_t)(uint8_t)buf[line + byte]];
    }
    if (buffered > 0) {
      bytes_written += base_fprintf(out, "%!s", buffered, glyph_buffer);
    }
    bytes_written += base_fprintf(out, "\n");
  }

  return bytes_written;
}
