// Copyright 2020 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// ----------------

// print-json-token-debug-format.c parses JSON from stdin and prints the
// resulting token stream, eliding any non-essential (e.g. whitespace) tokens.
//
// The output format is only for debugging or regression testing, and certainly
// not for long term storage. It isn't guaranteed to be stable between versions
// of this program and of the Wuffs standard library.
//
// It prints 16 bytes (128 bits) per token, containing big-endian numbers:
//
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// |               |       |       |   |      VALUE_EXTENSION      |
// |      POS      |  LEN  |  CON  |EXT|VALUE_MAJOR|  VALUE_MINOR  |
// |               |       |       |   |     0     |VBC|    VBD    |
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//
//  - POS (4 bytes) is the position: the sum of all previous tokens' lengths,
//                  including elided tokens.
//  - LEN (2 bytes) is the length.
//  - CON (2 bytes) is the continued bit
//  - EXT (1 bytes) is 1 for extended and 0 for simple tokens.
//
// Extended tokens have a VALUE_EXTENSION (7 bytes).
//
// Simple tokens have a VALUE_MAJOR (3 bytes) and then either 4 bytes
// VALUE_MINOR (when VALUE_MAJOR is non-zero) or (1 + 3) bytes
// VALUE_BASE_CATEGORY and VALUE_BASE_DETAIL (when VALUE_MAJOR is zero).
//
// ----
//
// Together with the hexadecimal WUFFS_BASE__TOKEN__ETC constants defined in
// token-public.h, this format is somewhat human-readable when piped through a
// hex-dump program (such as /usr/bin/hd), printing one token per line.
// Alternatively, pass the -h (--human-readable) flag to this program.
//
// Pass -a (--all-tokens) to print all tokens, including whitespace.
//
// If the input or output is larger than the program's buffers (64 MiB and
// 131072 tokens by default), there may be multiple valid tokenizations of any
// given input. For example, if a source string "abcde" straddles an I/O
// boundary, it may be tokenized as single (not continued) 5-length string or
// as a 3-length continued string followed by a 2-length string.
//
// A Wuffs token stream, in general, can support inputs more than 0xFFFF_FFFF
// bytes long, but this program can not, as it tracks the tokens' cumulative
// position as a uint32.

#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

// Wuffs ships as a "single file C library" or "header file library" as per
// https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
//
// To use that single file as a "foo.c"-like implementation, instead of a
// "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or
// compiling it.
#define WUFFS_IMPLEMENTATION

// Defining the WUFFS_CONFIG__MODULE* macros are optional, but it lets users of
// release/c/etc.c whitelist which parts of Wuffs to build. That file contains
// the entire Wuffs standard library, implementing a variety of codecs and file
// formats. Without this macro definition, an optimizing compiler or linker may
// very well discard Wuffs code for unused codecs, but listing the Wuffs
// modules we use makes that process explicit. Preprocessing means that such
// code simply isn't compiled.
#define WUFFS_CONFIG__MODULES
#define WUFFS_CONFIG__MODULE__BASE
#define WUFFS_CONFIG__MODULE__CBOR
#define WUFFS_CONFIG__MODULE__JSON

// If building this program in an environment that doesn't easily accommodate
// relative includes, you can use the script/inline-c-relative-includes.go
// program to generate a stand-alone C++ file.
#include "../release/c/wuffs-unsupported-snapshot.c"

// Wuffs allows either statically or dynamically allocated work buffers. This
// program exercises static allocation.
#if WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE > \
    WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE
#define WORK_BUFFER_ARRAY_SIZE \
  WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE
#else
#define WORK_BUFFER_ARRAY_SIZE \
  WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE
#endif
#if WORK_BUFFER_ARRAY_SIZE > 0
uint8_t g_work_buffer_array[WORK_BUFFER_ARRAY_SIZE];
#else
// Not all C/C++ compilers support 0-length arrays.
uint8_t g_work_buffer_array[1];
#endif

#ifndef SRC_BUFFER_ARRAY_SIZE
#define SRC_BUFFER_ARRAY_SIZE (64 * 1024 * 1024)
#endif
#ifndef TOKEN_BUFFER_ARRAY_SIZE
#define TOKEN_BUFFER_ARRAY_SIZE (128 * 1024)
#endif

uint8_t g_src_buffer_array[SRC_BUFFER_ARRAY_SIZE];
wuffs_base__token g_tok_buffer_array[TOKEN_BUFFER_ARRAY_SIZE];

wuffs_base__io_buffer g_src;
wuffs_base__token_buffer g_tok;

wuffs_cbor__decoder g_cbor_decoder;
wuffs_json__decoder g_json_decoder;
wuffs_base__token_decoder* g_dec;
wuffs_base__status g_dec_status;

#define TRY(error_msg)         \
  do {                         \
    const char* z = error_msg; \
    if (z) {                   \
      return z;                \
    }                          \
  } while (false)

// ignore_return_value suppresses errors from -Wall -Werror.
static void  //
ignore_return_value(int ignored) {}

const char*  //
read_src() {
  if (g_src.meta.closed) {
    return "main: internal error: read requested on a closed source";
  }
  wuffs_base__io_buffer__compact(&g_src);
  if (g_src.meta.wi >= g_src.data.len) {
    return "main: g_src buffer is full";
  }
  size_t n = fread(g_src.data.ptr + g_src.meta.wi, sizeof(uint8_t),
                   g_src.data.len - g_src.meta.wi, stdin);
  g_src.meta.wi += n;
  g_src.meta.closed = feof(stdin);
  if ((n == 0) && !g_src.meta.closed) {
    return "main: read error";
  }
  return NULL;
}

// ----

typedef enum file_format_enum {
  FILE_FORMAT_JSON,
  FILE_FORMAT_CBOR,
} file_format;

struct {
  int remaining_argc;
  char** remaining_argv;

  bool all_tokens;
  bool human_readable;
  file_format input_format;
  bool quirks;
} g_flags = {0};

const char*  //
parse_flags(int argc, char** argv) {
  int c = (argc > 0) ? 1 : 0;  // Skip argv[0], the program name.
  for (; c < argc; c++) {
    char* arg = argv[c];
    if (*arg++ != '-') {
      break;
    }

    // A double-dash "--foo" is equivalent to a single-dash "-foo". As special
    // cases, a bare "-" is not a flag (some programs may interpret it as
    // stdin) and a bare "--" means to stop parsing flags.
    if (*arg == '\x00') {
      break;
    } else if (*arg == '-') {
      arg++;
      if (*arg == '\x00') {
        c++;
        break;
      }
    }

    if (!strcmp(arg, "a") || !strcmp(arg, "all-tokens")) {
      g_flags.all_tokens = true;
      continue;
    }
    if (!strcmp(arg, "h") || !strcmp(arg, "human-readable")) {
      g_flags.human_readable = true;
      continue;
    }
    if (!strcmp(arg, "i=cbor") || !strcmp(arg, "input-format=cbor")) {
      g_flags.input_format = FILE_FORMAT_CBOR;
      continue;
    }
    if (!strcmp(arg, "i=json") || !strcmp(arg, "input-format=json")) {
      g_flags.input_format = FILE_FORMAT_JSON;
      continue;
    }
    if (!strcmp(arg, "q") || !strcmp(arg, "quirks")) {
      g_flags.quirks = true;
      continue;
    }

    return "main: unrecognized flag argument";
  }

  g_flags.remaining_argc = argc - c;
  g_flags.remaining_argv = argv + c;
  return NULL;
}

const char* g_vbc_names[16] = {
    "0:Filler...........",  //
    "1:Structure........",  //
    "2:String...........",  //
    "3:UnicodeCodePoint.",  //
    "4:Literal..........",  //
    "5:Number...........",  //
    "6:InlineIntSigned..",  //
    "7:InlineIntUnsigned",  //
    "8:Reserved.........",  //
    "9:Reserved.........",  //
    "A:Reserved.........",  //
    "B:Reserved.........",  //
    "C:Reserved.........",  //
    "D:Reserved.........",  //
    "E:Reserved.........",  //
    "F:Reserved.........",  //
};

const int g_base38_decode[38] = {
    ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '?',       //
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',  //
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',  //
};

const char*  //
main1(int argc, char** argv) {
  TRY(parse_flags(argc, argv));
  if (g_flags.remaining_argc > 0) {
    return "main: bad argument: use \"program < input\", not \"program input\"";
  }

  g_src = wuffs_base__make_io_buffer(
      wuffs_base__make_slice_u8(g_src_buffer_array, SRC_BUFFER_ARRAY_SIZE),
      wuffs_base__empty_io_buffer_meta());

  g_tok = wuffs_base__make_token_buffer(
      wuffs_base__make_slice_token(g_tok_buffer_array, TOKEN_BUFFER_ARRAY_SIZE),
      wuffs_base__empty_token_buffer_meta());

  if (g_flags.input_format == FILE_FORMAT_JSON) {
    wuffs_base__status init_status = wuffs_json__decoder__initialize(
        &g_json_decoder, sizeof__wuffs_json__decoder(), WUFFS_VERSION, 0);
    if (!wuffs_base__status__is_ok(&init_status)) {
      return wuffs_base__status__message(&init_status);
    }
    g_dec = wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(
        &g_json_decoder);
  } else {
    wuffs_base__status init_status = wuffs_cbor__decoder__initialize(
        &g_cbor_decoder, sizeof__wuffs_cbor__decoder(), WUFFS_VERSION, 0);
    if (!wuffs_base__status__is_ok(&init_status)) {
      return wuffs_base__status__message(&init_status);
    }
    g_dec = wuffs_cbor__decoder__upcast_as__wuffs_base__token_decoder(
        &g_cbor_decoder);
  }

  if (g_flags.quirks) {
    uint32_t quirks[] = {
        WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_A,
        WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_CAPITAL_U,
        WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_E,
        WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_QUESTION_MARK,
        WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE,
        WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_V,
        WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_X_AS_CODE_POINTS,
        WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_ZERO,
        WUFFS_JSON__QUIRK_ALLOW_COMMENT_BLOCK,
        WUFFS_JSON__QUIRK_ALLOW_COMMENT_LINE,
        WUFFS_JSON__QUIRK_ALLOW_EXTRA_COMMA,
        WUFFS_JSON__QUIRK_ALLOW_INF_NAN_NUMBERS,
        WUFFS_JSON__QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR,
        WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK,
        WUFFS_JSON__QUIRK_ALLOW_TRAILING_NEW_LINE,
        WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE,
        0,
    };
    uint32_t i;
    for (i = 0; quirks[i]; i++) {
      wuffs_base__token_decoder__set_quirk_enabled(g_dec, quirks[i], true);
    }
  }

  uint64_t pos = 0;
  while (true) {
    wuffs_base__status status = wuffs_base__token_decoder__decode_tokens(
        g_dec, &g_tok, &g_src,
        wuffs_base__make_slice_u8(g_work_buffer_array, WORK_BUFFER_ARRAY_SIZE));

    while (g_tok.meta.ri < g_tok.meta.wi) {
      wuffs_base__token* t = &g_tok.data.ptr[g_tok.meta.ri++];
      uint16_t len = wuffs_base__token__length(t);

      if (g_flags.all_tokens || (wuffs_base__token__value(t) != 0)) {
        uint16_t con = wuffs_base__token__continued(t) ? 1 : 0;
        int32_t vmajor = wuffs_base__token__value_major(t);
        uint32_t vminor = wuffs_base__token__value_minor(t);
        uint8_t vbc = wuffs_base__token__value_base_category(t);
        uint32_t vbd = wuffs_base__token__value_base_detail(t);

        if (g_flags.human_readable) {
          printf("pos=0x%08" PRIX32 "  len=0x%04" PRIX16 "  con=%" PRId16 "  ",
                 (uint32_t)(pos), len, con);

          if (vmajor > 0) {
            char vmajor_name[5];
            vmajor_name[0] = '*';
            vmajor_name[1] = '*';
            vmajor_name[2] = '*';
            vmajor_name[3] = '*';
            vmajor_name[4] = '\x00';
            uint32_t m = vmajor;
            if (m < 38 * 38 * 38 * 38) {
              uint32_t m0 = m / (38 * 38 * 38);
              m -= m0 * (38 * 38 * 38);
              vmajor_name[0] = g_base38_decode[m0];

              uint32_t m1 = m / (38 * 38);
              m -= m1 * (38 * 38);
              vmajor_name[1] = g_base38_decode[m1];

              uint32_t m2 = m / (38);
              m -= m2 * (38);
              vmajor_name[2] = g_base38_decode[m2];

              uint32_t m3 = m;
              vmajor_name[3] = g_base38_decode[m3];
            }

            printf("vmajor=0x%06" PRIX32 ":%s vminor=0x%07" PRIX32 "\n", vmajor,
                   vmajor_name, vminor);
          } else if (vmajor == 0) {
            printf("vbc=%s  vbd=0x%06" PRIX32 "\n", g_vbc_names[vbc & 15], vbd);
          } else {
            printf("extended... vextension=0x%012" PRIX64 "\n",
                   wuffs_base__token__value_extension(t));
          }

        } else {
          uint8_t buf[16];
          wuffs_base__store_u32be__no_bounds_check(&buf[0x0], (uint32_t)(pos));
          wuffs_base__store_u16be__no_bounds_check(&buf[0x4], len);
          wuffs_base__store_u16be__no_bounds_check(&buf[0x6], con);
          if (vmajor > 0) {
            wuffs_base__store_u32be__no_bounds_check(&buf[0x8], vmajor);
            wuffs_base__store_u32be__no_bounds_check(&buf[0xC], vminor);
          } else if (vmajor == 0) {
            wuffs_base__store_u32be__no_bounds_check(&buf[0x8], 0);
            wuffs_base__store_u8__no_bounds_check(&buf[0x000C], vbc);
            wuffs_base__store_u24be__no_bounds_check(&buf[0xD], vbd);
          } else {
            wuffs_base__store_u8__no_bounds_check(&buf[0x0008], 0x01);
            wuffs_base__store_u56be__no_bounds_check(
                &buf[0x9], wuffs_base__token__value_extension(t));
          }
          const int stdout_fd = 1;
          ignore_return_value(write(stdout_fd, &buf[0], 16));
        }
      }

      pos += len;
      if (pos > 0xFFFFFFFF) {
        return "main: input is too long";
      }
    }

    if (status.repr == NULL) {
      return NULL;
    } else if (status.repr == wuffs_base__suspension__short_read) {
      TRY(read_src());
    } else if (status.repr == wuffs_base__suspension__short_write) {
      wuffs_base__token_buffer__compact(&g_tok);
    } else {
      return wuffs_base__status__message(&status);
    }
  }
}

// ----

int  //
compute_exit_code(const char* status_msg) {
  if (!status_msg) {
    return 0;
  }
  size_t n = strnlen(status_msg, 2047);
  if (n >= 2047) {
    status_msg = "main: internal error: error message is too long";
    n = strnlen(status_msg, 2047);
  }
  fprintf(stderr, "%s\n", status_msg);
  // Return an exit code of 1 for regular (forseen) errors, e.g. badly
  // formatted or unsupported input.
  //
  // Return an exit code of 2 for internal (exceptional) errors, e.g. defensive
  // run-time checks found that an internal invariant did not hold.
  //
  // Automated testing, including badly formatted inputs, can therefore
  // discriminate between expected failure (exit code 1) and unexpected failure
  // (other non-zero exit codes). Specifically, exit code 2 for internal
  // invariant violation, exit code 139 (which is 128 + SIGSEGV on x86_64
  // linux) for a segmentation fault (e.g. null pointer dereference).
  return strstr(status_msg, "internal error:") ? 2 : 1;
}

int  //
main(int argc, char** argv) {
  const char* z = main1(argc, argv);
  int exit_code = compute_exit_code(z);
  return exit_code;
}
