// 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.

// ---------------- Auxiliary - JSON

#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__JSON)

#include <utility>

namespace wuffs_aux {

DecodeJsonResult::DecodeJsonResult(std::string&& error_message0,
                                   uint64_t cursor_position0)
    : error_message(std::move(error_message0)),
      cursor_position(cursor_position0) {}

DecodeJsonCallbacks::~DecodeJsonCallbacks() {}

void  //
DecodeJsonCallbacks::Done(DecodeJsonResult& result,
                          sync_io::Input& input,
                          IOBuffer& buffer) {}

const char DecodeJson_BadJsonPointer[] =  //
    "wuffs_aux::DecodeJson: bad JSON Pointer";
const char DecodeJson_NoMatch[] =  //
    "wuffs_aux::DecodeJson: no match";

DecodeJsonArgQuirks::DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0)
    : repr(repr0) {}

DecodeJsonArgQuirks::DecodeJsonArgQuirks(uint32_t* ptr0, size_t len0)
    : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}

DecodeJsonArgQuirks  //
DecodeJsonArgQuirks::DefaultValue() {
  return DecodeJsonArgQuirks(wuffs_base__empty_slice_u32());
}

DecodeJsonArgJsonPointer::DecodeJsonArgJsonPointer(std::string repr0)
    : repr(repr0) {}

DecodeJsonArgJsonPointer  //
DecodeJsonArgJsonPointer::DefaultValue() {
  return DecodeJsonArgJsonPointer(std::string());
}

// --------

#define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN                          \
  while (tok_buf.meta.ri >= tok_buf.meta.wi) {                              \
    if (tok_status.repr == nullptr) {                                       \
      goto done;                                                            \
    } else if (tok_status.repr == wuffs_base__suspension__short_write) {    \
      tok_buf.compact();                                                    \
    } else if (tok_status.repr == wuffs_base__suspension__short_read) {     \
      if (!io_error_message.empty()) {                                      \
        ret_error_message = std::move(io_error_message);                    \
        goto done;                                                          \
      } else if (cursor_index != io_buf->meta.ri) {                         \
        ret_error_message =                                                 \
            "wuffs_aux::DecodeJson: internal error: bad cursor_index";      \
        goto done;                                                          \
      } else if (io_buf->meta.closed) {                                     \
        ret_error_message =                                                 \
            "wuffs_aux::DecodeJson: internal error: io_buf is closed";      \
        goto done;                                                          \
      }                                                                     \
      io_buf->compact();                                                    \
      if (io_buf->meta.wi >= io_buf->data.len) {                            \
        ret_error_message =                                                 \
            "wuffs_aux::DecodeJson: internal error: io_buf is full";        \
        goto done;                                                          \
      }                                                                     \
      cursor_index = io_buf->meta.ri;                                       \
      io_error_message = input.CopyIn(io_buf);                              \
    } else {                                                                \
      ret_error_message = tok_status.message();                             \
      goto done;                                                            \
    }                                                                       \
    tok_status =                                                            \
        dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \
    if ((tok_buf.meta.ri > tok_buf.meta.wi) ||                              \
        (tok_buf.meta.wi > tok_buf.data.len) ||                             \
        (io_buf->meta.ri > io_buf->meta.wi) ||                              \
        (io_buf->meta.wi > io_buf->data.len)) {                             \
      ret_error_message =                                                   \
          "wuffs_aux::DecodeJson: internal error: bad buffer indexes";      \
      goto done;                                                            \
    }                                                                       \
  }                                                                         \
  wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];            \
  uint64_t token_len = token.length();                                      \
  if ((io_buf->meta.ri < cursor_index) ||                                   \
      ((io_buf->meta.ri - cursor_index) < token_len)) {                     \
    ret_error_message =                                                     \
        "wuffs_aux::DecodeJson: internal error: bad token indexes";         \
    goto done;                                                              \
  }                                                                         \
  uint8_t* token_ptr = io_buf->data.ptr + cursor_index;                     \
  (void)(token_ptr);                                                        \
  cursor_index += static_cast<size_t>(token_len)

// --------

namespace {

// DecodeJson_SplitJsonPointer returns ("bar", 8) for ("/foo/bar/b~1z/qux", 5,
// etc). It returns a 0 size_t when s has invalid JSON Pointer syntax or i is
// out of bounds.
//
// The string returned is unescaped. If calling it again, this time with i=8,
// the "b~1z" substring would be returned as "b/z".
std::pair<std::string, size_t>  //
DecodeJson_SplitJsonPointer(std::string& s,
                            size_t i,
                            bool allow_tilde_n_tilde_r_tilde_t) {
  std::string fragment;
  if (i > s.size()) {
    return std::make_pair(std::string(), 0);
  }
  while (i < s.size()) {
    char c = s[i];
    if (c == '/') {
      break;
    } else if (c != '~') {
      fragment.push_back(c);
      i++;
      continue;
    }
    i++;
    if (i >= s.size()) {
      return std::make_pair(std::string(), 0);
    }
    c = s[i];
    if (c == '0') {
      fragment.push_back('~');
      i++;
      continue;
    } else if (c == '1') {
      fragment.push_back('/');
      i++;
      continue;
    } else if (allow_tilde_n_tilde_r_tilde_t) {
      if (c == 'n') {
        fragment.push_back('\n');
        i++;
        continue;
      } else if (c == 'r') {
        fragment.push_back('\r');
        i++;
        continue;
      } else if (c == 't') {
        fragment.push_back('\t');
        i++;
        continue;
      }
    }
    return std::make_pair(std::string(), 0);
  }
  return std::make_pair(std::move(fragment), i);
}

// --------

std::string  //
DecodeJson_WalkJsonPointerFragment(wuffs_base__token_buffer& tok_buf,
                                   wuffs_base__status& tok_status,
                                   wuffs_json__decoder::unique_ptr& dec,
                                   wuffs_base__io_buffer* io_buf,
                                   std::string& io_error_message,
                                   size_t& cursor_index,
                                   sync_io::Input& input,
                                   std::string& json_pointer_fragment) {
  std::string ret_error_message;
  while (true) {
    WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;

    int64_t vbc = token.value_base_category();
    uint64_t vbd = token.value_base_detail();
    if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
      continue;
    } else if ((vbc != WUFFS_BASE__TOKEN__VBC__STRUCTURE) ||
               !(vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH)) {
      return DecodeJson_NoMatch;
    } else if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST) {
      goto do_list;
    }
    goto do_dict;
  }

do_dict:
  // Alternate between these two things:
  //  1. Decode the next dict key (a string). If it matches the fragment, we're
  //    done (success). If we've reached the dict's end (VBD__STRUCTURE__POP)
  //    so that there was no next dict key, we're done (failure).
  //  2. Otherwise, skip the next dict value.
  while (true) {
    for (std::string str; true;) {
      WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;

      int64_t vbc = token.value_base_category();
      uint64_t vbd = token.value_base_detail();
      switch (vbc) {
        case WUFFS_BASE__TOKEN__VBC__FILLER:
          continue;

        case WUFFS_BASE__TOKEN__VBC__STRUCTURE:
          if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
            goto fail;
          }
          return DecodeJson_NoMatch;

        case WUFFS_BASE__TOKEN__VBC__STRING: {
          if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
            // No-op.
          } else if (vbd &
                     WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
            const char* ptr =  // Convert from (uint8_t*).
                static_cast<const char*>(static_cast<void*>(token_ptr));
            str.append(ptr, static_cast<size_t>(token_len));
          } else {
            goto fail;
          }
          break;
        }

        case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
          uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
          size_t n = wuffs_base__utf_8__encode(
              wuffs_base__make_slice_u8(
                  &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
              static_cast<uint32_t>(vbd));
          const char* ptr =  // Convert from (uint8_t*).
              static_cast<const char*>(static_cast<void*>(&u[0]));
          str.append(ptr, n);
          break;
        }

        default:
          goto fail;
      }

      if (token.continued()) {
        continue;
      }
      if (str == json_pointer_fragment) {
        return "";
      }
      goto skip_the_next_dict_value;
    }

  skip_the_next_dict_value:
    for (uint32_t skip_depth = 0; true;) {
      WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;

      int64_t vbc = token.value_base_category();
      uint64_t vbd = token.value_base_detail();
      if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
        continue;
      } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
        if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
          skip_depth++;
          continue;
        }
        skip_depth--;
      }

      if (skip_depth == 0) {
        break;
      }
    }  // skip_the_next_dict_value
  }    // do_dict

do_list:
  do {
    wuffs_base__result_u64 result_u64 = wuffs_base__parse_number_u64(
        wuffs_base__make_slice_u8(
            static_cast<uint8_t*>(static_cast<void*>(
                const_cast<char*>(json_pointer_fragment.data()))),
            json_pointer_fragment.size()),
        WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
    if (!result_u64.status.is_ok()) {
      return DecodeJson_NoMatch;
    }
    uint64_t remaining = result_u64.value;
    if (remaining == 0) {
      goto check_that_a_value_follows;
    }
    for (uint32_t skip_depth = 0; true;) {
      WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;

      int64_t vbc = token.value_base_category();
      uint64_t vbd = token.value_base_detail();
      if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
        continue;
      } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
        if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
          skip_depth++;
          continue;
        }
        if (skip_depth == 0) {
          return DecodeJson_NoMatch;
        }
        skip_depth--;
      }

      if (skip_depth > 0) {
        continue;
      }
      remaining--;
      if (remaining == 0) {
        goto check_that_a_value_follows;
      }
    }
  } while (false);  // do_list

check_that_a_value_follows:
  while (true) {
    WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;

    int64_t vbc = token.value_base_category();
    uint64_t vbd = token.value_base_detail();
    if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
      continue;
    }

    // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so
    // that we're only peeking at the next token.
    tok_buf.meta.ri--;
    cursor_index -= static_cast<size_t>(token_len);

    if ((vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) &&
        (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP)) {
      return DecodeJson_NoMatch;
    }
    return "";
  }  // check_that_a_value_follows

fail:
  return "wuffs_aux::DecodeJson: internal error: unexpected token";
done:
  return ret_error_message;
}

}  // namespace

// --------

DecodeJsonResult  //
DecodeJson(DecodeJsonCallbacks& callbacks,
           sync_io::Input& input,
           DecodeJsonArgQuirks quirks,
           DecodeJsonArgJsonPointer json_pointer) {
  // Prepare the wuffs_base__io_buffer and the resultant error_message.
  wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
  wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
  std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
  if (!io_buf) {
    fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
    fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
    io_buf = &fallback_io_buf;
  }
  // cursor_index is discussed at
  // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
  size_t cursor_index = 0;
  std::string ret_error_message;
  std::string io_error_message;

  do {
    // Prepare the low-level JSON decoder.
    wuffs_json__decoder::unique_ptr dec = wuffs_json__decoder::alloc();
    if (!dec) {
      ret_error_message = "wuffs_aux::DecodeJson: out of memory";
      goto done;
    } else if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
      ret_error_message =
          "wuffs_aux::DecodeJson: internal error: bad WORKBUF_LEN";
      goto done;
    }
    bool allow_tilde_n_tilde_r_tilde_t = false;
    for (size_t i = 0; i < quirks.repr.len; i++) {
      dec->set_quirk(quirks.repr.ptr[i], 1);
      if (quirks.repr.ptr[i] ==
          WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T) {
        allow_tilde_n_tilde_r_tilde_t = true;
      }
    }

    // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
    wuffs_base__token tok_array[256];
    wuffs_base__token_buffer tok_buf =
        wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
            &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
    wuffs_base__status tok_status =
        dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());

    // Prepare other state.
    int32_t depth = 0;
    std::string str;

    // Walk the (optional) JSON Pointer.
    for (size_t i = 0; i < json_pointer.repr.size();) {
      if (json_pointer.repr[i] != '/') {
        ret_error_message = DecodeJson_BadJsonPointer;
        goto done;
      }
      std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(
          json_pointer.repr, i + 1, allow_tilde_n_tilde_r_tilde_t);
      i = split.second;
      if (i == 0) {
        ret_error_message = DecodeJson_BadJsonPointer;
        goto done;
      }
      ret_error_message = DecodeJson_WalkJsonPointerFragment(
          tok_buf, tok_status, dec, io_buf, io_error_message, cursor_index,
          input, split.first);
      if (!ret_error_message.empty()) {
        goto done;
      }
    }

    // Loop, doing these two things:
    //  1. Get the next token.
    //  2. Process that token.
    while (true) {
      WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;

      int64_t vbc = token.value_base_category();
      uint64_t vbd = token.value_base_detail();
      switch (vbc) {
        case WUFFS_BASE__TOKEN__VBC__FILLER:
          continue;

        case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
          if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
            ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
            if (!ret_error_message.empty()) {
              goto done;
            }
            depth++;
            if (depth > WUFFS_JSON__DECODER_DEPTH_MAX_INCL) {
              ret_error_message =
                  "wuffs_aux::DecodeJson: internal error: bad depth";
              goto done;
            }
            continue;
          }
          ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
          depth--;
          if (depth < 0) {
            ret_error_message =
                "wuffs_aux::DecodeJson: internal error: bad depth";
            goto done;
          }
          goto parsed_a_value;
        }

        case WUFFS_BASE__TOKEN__VBC__STRING: {
          if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
            // No-op.
          } else if (vbd &
                     WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
            const char* ptr =  // Convert from (uint8_t*).
                static_cast<const char*>(static_cast<void*>(token_ptr));
            str.append(ptr, static_cast<size_t>(token_len));
          } else {
            goto fail;
          }
          if (token.continued()) {
            continue;
          }
          ret_error_message = callbacks.AppendTextString(std::move(str));
          str.clear();
          goto parsed_a_value;
        }

        case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
          uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
          size_t n = wuffs_base__utf_8__encode(
              wuffs_base__make_slice_u8(
                  &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
              static_cast<uint32_t>(vbd));
          const char* ptr =  // Convert from (uint8_t*).
              static_cast<const char*>(static_cast<void*>(&u[0]));
          str.append(ptr, n);
          if (token.continued()) {
            continue;
          }
          goto fail;
        }

        case WUFFS_BASE__TOKEN__VBC__LITERAL: {
          ret_error_message =
              (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL)
                  ? callbacks.AppendNull()
                  : callbacks.AppendBool(vbd &
                                         WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
          goto parsed_a_value;
        }

        case WUFFS_BASE__TOKEN__VBC__NUMBER: {
          if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT) {
            if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED) {
              wuffs_base__result_i64 r = wuffs_base__parse_number_i64(
                  wuffs_base__make_slice_u8(token_ptr,
                                            static_cast<size_t>(token_len)),
                  WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
              if (r.status.is_ok()) {
                ret_error_message = callbacks.AppendI64(r.value);
                goto parsed_a_value;
              }
            }
            if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT) {
              wuffs_base__result_f64 r = wuffs_base__parse_number_f64(
                  wuffs_base__make_slice_u8(token_ptr,
                                            static_cast<size_t>(token_len)),
                  WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
              if (r.status.is_ok()) {
                ret_error_message = callbacks.AppendF64(r.value);
                goto parsed_a_value;
              }
            }
          } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF) {
            ret_error_message = callbacks.AppendF64(
                wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
                    0xFFF0000000000000ul));
            goto parsed_a_value;
          } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF) {
            ret_error_message = callbacks.AppendF64(
                wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
                    0x7FF0000000000000ul));
            goto parsed_a_value;
          } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN) {
            ret_error_message = callbacks.AppendF64(
                wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
                    0xFFFFFFFFFFFFFFFFul));
            goto parsed_a_value;
          } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN) {
            ret_error_message = callbacks.AppendF64(
                wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
                    0x7FFFFFFFFFFFFFFFul));
            goto parsed_a_value;
          }
          goto fail;
        }
      }

    fail:
      ret_error_message =
          "wuffs_aux::DecodeJson: internal error: unexpected token";
      goto done;

    parsed_a_value:
      // If an error was encountered, we are done. Otherwise, (depth == 0)
      // after parsing a value is equivalent to having decoded the entire JSON
      // value (for an empty json_pointer query) or having decoded the
      // pointed-to JSON value (for a non-empty json_pointer query). In the
      // latter case, we are also done.
      //
      // However, if quirks like WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or
      // WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF are passed, decoding
      // the entire JSON value should also consume any trailing filler, in case
      // the DecodeJson caller wants to subsequently check that the input is
      // completely exhausted (and otherwise raise "valid JSON followed by
      // further (unexpected) data"). We aren't done yet. Instead, keep the
      // loop running until WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN's
      // decode_tokens returns an ok status.
      if (!ret_error_message.empty() ||
          ((depth == 0) && !json_pointer.repr.empty())) {
        goto done;
      }
    }
  } while (false);

done:
  DecodeJsonResult result(
      std::move(ret_error_message),
      wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
  callbacks.Done(result, input, *io_buf);
  return result;
}

#undef WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN

}  // namespace wuffs_aux

#endif  // !defined(WUFFS_CONFIG__MODULES) ||
        // defined(WUFFS_CONFIG__MODULE__AUX__JSON)
