/** @file

  Helpers for parsing log field fallback expressions.

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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

      http://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.
 */

#include "LogFieldFallback.h"

#include <cctype>
#include <string>
#include <string_view>
#include <utility>

#include "swoc/TextView.h"

namespace
{
constexpr std::string_view FIELD_FALLBACK_SEPARATOR{"??"};

/** Find the next fallback separator outside of quoted default literals.
 *
 * This keeps the chain tokenizer from splitting on separator text that is
 * part of a quoted default value.
 *
 * @param[in] text Candidate fallback expression text.
 * @return Pointer to the first separator occurrence, or @c nullptr if none.
 */
constexpr char const *
find_field_fallback_separator(std::string_view text)
{
  char quote  = '\0';
  bool escape = false;

  // The following logic assumes a 2 character separator. If that changes,
  // adjust the logic accordingly.
  static_assert(FIELD_FALLBACK_SEPARATOR.size() == 2, "FIELD_FALLBACK_SEPARATOR must be exactly two characters long");

  for (auto const *spot = text.data(), *limit = text.data() + text.size(); spot < limit; ++spot) {
    char c = *spot;

    if (quote != '\0') {
      if (escape) {
        escape = false;
      } else if (c == '\\') {
        escape = true;
      } else if (c == quote) {
        quote = '\0';
      }
      continue;
    }

    if (c == '\'' || c == '"') {
      quote = c;
      continue;
    }

    if (*spot == FIELD_FALLBACK_SEPARATOR[0] && (spot + 1) < limit && *(spot + 1) == FIELD_FALLBACK_SEPARATOR[1]) {
      return spot;
    }
  }

  return nullptr;
}

constexpr bool
test_find_field_fallback_separator()
{
  static_assert(find_field_fallback_separator("") == nullptr);
  [[maybe_unused]] constexpr char text1[] = "{field}??default";
  static_assert(find_field_fallback_separator(text1) == text1 + 7);
  [[maybe_unused]] constexpr char text2[] = "??default";
  static_assert(find_field_fallback_separator(text2) == text2);
  [[maybe_unused]] constexpr char text3[] = "{field}??def??ault";
  static_assert(find_field_fallback_separator(text3) == text3 + 7);
  [[maybe_unused]] constexpr char text4[] = "{field}??\"def??ault\"";
  static_assert(find_field_fallback_separator(text4) == text4 + 7);
  return true;
}

static_assert(test_find_field_fallback_separator(), "find_field_fallback_separator failed its tests");

void
set_parse_error(std::string &error, std::string_view symbol, std::string_view detail)
{
  error.assign("Invalid log field fallback specification: ");
  error.append(detail.data(), detail.size());
  error.append(" in ");
  error.append(symbol.data(), symbol.size());
}

bool
parse_header_fallback_candidate(swoc::TextView term, LogField::HeaderField &field, std::string_view original_symbol,
                                std::string &error)
{
  term.trim_if(isspace);
  std::string term_text{term};

  if (term_text.empty()) {
    set_parse_error(error, original_symbol, "empty candidate");
    return false;
  }

  if (term_text.front() != '{') {
    set_parse_error(error, original_symbol, term_text + " is not a header field candidate");
    return false;
  }

  term.remove_prefix(1);
  size_t name_end = term.find('}');
  if (name_end == swoc::TextView::npos) {
    set_parse_error(error, original_symbol, "no trailing '}'");
    return false;
  }

  swoc::TextView field_name = term.substr(0, name_end);
  if (field_name.empty()) {
    set_parse_error(error, original_symbol, "empty header name");
    return false;
  }

  swoc::TextView container_text = term.substr(name_end + 1);
  container_text.trim_if(isspace);
  std::string container_spec{container_text};
  LogSlice    slice(container_spec.data());
  auto        container = LogField::valid_container_name(container_spec.data());

  if (!LogField::isHeaderContainer(container)) {
    set_parse_error(error, original_symbol, container_spec + " is not a supported header container");
    return false;
  }

  field.name.assign(field_name.data(), field_name.size());
  field.container = container;
  field.slice     = slice;

  return true;
}

bool
parse_field_fallback_symbol(swoc::TextView term, std::string &field_symbol, std::string_view original_symbol, std::string &error)
{
  term.trim_if(isspace);
  if (term.empty()) {
    set_parse_error(error, original_symbol, "empty candidate");
    return false;
  }

  if (term.find('(') != swoc::TextView::npos || term.find(')') != swoc::TextView::npos) {
    set_parse_error(error, original_symbol, "aggregate expressions are not supported in fallback chains");
    return false;
  }

  if (term.find('{') != swoc::TextView::npos || term.find('}') != swoc::TextView::npos) {
    set_parse_error(error, original_symbol, std::string{term} + " is not a supported fallback term");
    return false;
  }

  field_symbol.assign(term.data(), term.size());
  return true;
}

bool
parse_field_fallback_default(swoc::TextView term, std::string &default_value, std::string_view original_symbol, std::string &error)
{
  term.trim_if(isspace);
  if (term.empty()) {
    set_parse_error(error, original_symbol, "empty default");
    return false;
  }

  char quote = term.front();
  if (quote != '\'' && quote != '"') {
    set_parse_error(error, original_symbol, std::string{term} + " is not a quoted default literal");
    return false;
  }

  default_value.clear();
  bool escaped = false;

  for (auto const *spot = term.data() + 1, *limit = term.data_end(); spot < limit; ++spot) {
    char c = *spot;

    if (escaped) {
      if (c == quote || c == '\\') {
        default_value.push_back(c);
      } else {
        default_value.push_back('\\');
        default_value.push_back(c);
      }
      escaped = false;
      continue;
    }

    if (c == '\\') {
      escaped = true;
      continue;
    }

    if (c == quote) {
      if (spot + 1 != limit) {
        set_parse_error(error, original_symbol, "trailing characters after default literal");
        return false;
      }
      return true;
    }

    default_value.push_back(c);
  }

  set_parse_error(error, original_symbol, "unterminated default literal");
  return false;
}
} // namespace

namespace LogFieldFallback
{
bool
has_fallback(std::string_view symbol)
{
  return find_field_fallback_separator(symbol) != nullptr;
}

std::optional<ParseResult>
parse(std::string_view symbol, std::string &error)
{
  error.clear();

  ParseResult    result;
  swoc::TextView remaining{symbol};

  while (true) {
    swoc::TextView term;
    bool           has_more_terms = false;

    if (auto const *separator = find_field_fallback_separator(remaining); separator != nullptr) {
      term = swoc::TextView{remaining.data(), static_cast<size_t>(separator - remaining.data())};
      remaining.remove_prefix((separator - remaining.data()) + FIELD_FALLBACK_SEPARATOR.size());
      has_more_terms = true;
    } else {
      term      = remaining;
      remaining = swoc::TextView{};
    }

    term.trim_if(isspace);
    if (term.empty()) {
      set_parse_error(error, symbol, "empty candidate");
      return std::nullopt;
    }

    if (term.starts_with('"') || term.starts_with('\'')) {
      if (has_more_terms) {
        set_parse_error(error, symbol, "default literal must be the final term");
        return std::nullopt;
      }

      std::string fallback_default;
      if (!parse_field_fallback_default(term, fallback_default, symbol, error)) {
        return std::nullopt;
      }
      result.fallback_default = std::move(fallback_default);
      break;
    }

    if (term.starts_with('{')) {
      LogField::HeaderField field;
      if (!parse_header_fallback_candidate(term, field, symbol, error)) {
        return std::nullopt;
      }

      result.header_fields.push_back(std::move(field));

      if (!has_more_terms) {
        break;
      }
    } else {
      if (has_more_terms) {
        set_parse_error(error, symbol, "plain field symbols must be the final term");
        return std::nullopt;
      }

      std::string fallback_symbol;
      if (!parse_field_fallback_symbol(term, fallback_symbol, symbol, error)) {
        return std::nullopt;
      }

      result.fallback_symbol = std::move(fallback_symbol);
      break;
    }
  }

  if (result.header_fields.empty()) {
    set_parse_error(error, symbol, "must start with a header field candidate");
    return std::nullopt;
  }

  return result;
}
} // namespace LogFieldFallback
