// Copyright 2023 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quiche/web_transport/web_transport_headers.h"

#include <array>
#include <cstdint>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/base/attributes.h"
#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/common/quiche_status_utils.h"
#include "quiche/common/structured_headers.h"

namespace webtransport {

namespace {
using ::quiche::structured_headers::Dictionary;
using ::quiche::structured_headers::DictionaryMember;
using ::quiche::structured_headers::Item;
using ::quiche::structured_headers::ItemTypeToString;
using ::quiche::structured_headers::List;
using ::quiche::structured_headers::ParameterizedItem;
using ::quiche::structured_headers::ParameterizedMember;

template <Item::ItemType kExpectedType>
auto* GetItemAsPtr(auto&& item) {
  if constexpr (kExpectedType == Item::kIntegerType) {
    return item.item.GetIfInteger();
  } else if constexpr (kExpectedType == Item::kStringType) {
    return item.item.GetIfString();
  } else {
    static_assert(false);
  }
}

template <Item::ItemType kExpectedType>
auto GetItem(auto&& item) -> absl::StatusOr<
    std::remove_pointer_t<decltype(GetItemAsPtr<kExpectedType>(item))>> {
  auto* ptr = GetItemAsPtr<kExpectedType>(item);
  if (!ptr) {
    return absl::InvalidArgumentError(absl::StrCat(
        "Expected all members to be of type ", ItemTypeToString(kExpectedType),
        ", found ", ItemTypeToString(item.item.Type()), " instead"));
  }
  return std::move(*ptr);
}

template <Item::ItemType kExpectedType>
auto GetMember(auto&& member)
    -> decltype(GetItem<kExpectedType>(member.member[0])) {
  if (member.member_is_inner_list || member.member.size() != 1) {
    return absl::InvalidArgumentError(absl::StrCat(
        "Expected all members to be of type", ItemTypeToString(kExpectedType),
        ", found a nested list instead"));
  }
  return GetItem<kExpectedType>(member.member[0]);
}

ABSL_CONST_INIT std::array kInitHeaderFields{
    std::make_pair("u", &WebTransportInitHeader::initial_unidi_limit),
    std::make_pair("bl", &WebTransportInitHeader::initial_incoming_bidi_limit),
    std::make_pair("br", &WebTransportInitHeader::initial_outgoing_bidi_limit),
};
}  // namespace

absl::StatusOr<std::vector<std::string>> ParseSubprotocolRequestHeader(
    absl::string_view value) {
  std::optional<List> parsed = quiche::structured_headers::ParseList(value);
  if (!parsed.has_value()) {
    return absl::InvalidArgumentError(
        "Failed to parse the header as an sf-list");
  }

  std::vector<std::string> result;
  result.reserve(parsed->size());
  for (ParameterizedMember& member : *parsed) {
    QUICHE_ASSIGN_OR_RETURN(std::string v,
                            GetMember<Item::kStringType>(member));
    result.push_back(std::move(v));
  }
  return result;
}

absl::StatusOr<std::string> SerializeSubprotocolRequestHeader(
    absl::Span<const std::string> subprotocols) {
  quiche::structured_headers::List list;
  list.reserve(subprotocols.size());
  for (const std::string& subprotocol : subprotocols) {
    list.push_back(ParameterizedMember(Item(subprotocol), {}));
  }

  std::optional<std::string> serialized =
      quiche::structured_headers::SerializeList(list);
  if (!serialized.has_value()) {
    return absl::InvalidArgumentError("Invalid subprotocol list supplied");
  }
  return *std::move(serialized);
}

absl::StatusOr<std::string> ParseSubprotocolResponseHeader(
    absl::string_view value) {
  std::optional<ParameterizedItem> parsed =
      quiche::structured_headers::ParseItem(value);
  if (!parsed.has_value()) {
    return absl::InvalidArgumentError("Failed to parse sf-item");
  }
  return GetItem<Item::kStringType>(*parsed);
}

absl::StatusOr<std::string> SerializeSubprotocolResponseHeader(
    absl::string_view subprotocol) {
  Item item(std::string(subprotocol), Item::kStringType);
  std::optional<std::string> serialized =
      quiche::structured_headers::SerializeItem(item);
  if (!serialized.has_value()) {
    return absl::InvalidArgumentError("Invalid subprotocol name supplied");
  }
  return *std::move(serialized);
}

bool ValidateSubprotocolName(absl::string_view name) {
  return !name.empty() &&
         absl::c_all_of(name, [](char c) { return absl::ascii_isprint(c); });
}

template <typename S>
bool ValidateSubprotocolListBase(absl::Span<const S> list) {
  absl::flat_hash_set<absl::string_view> examined;
  for (const absl::string_view name : list) {
    if (!ValidateSubprotocolName(name)) {
      return false;
    }
    auto [it, added] = examined.insert(name);
    if (!added) {
      return false;
    }
  }
  return true;
}
bool ValidateSubprotocolList(absl::Span<const absl::string_view> list) {
  return ValidateSubprotocolListBase(list);
}
bool ValidateSubprotocolList(absl::Span<const std::string> list) {
  return ValidateSubprotocolListBase(list);
}

absl::StatusOr<WebTransportInitHeader> ParseInitHeader(
    absl::string_view header) {
  std::optional<Dictionary> parsed =
      quiche::structured_headers::ParseDictionary(header);
  if (!parsed.has_value()) {
    return absl::InvalidArgumentError(
        "Failed to parse WebTransport-Init header as an sf-dictionary");
  }
  WebTransportInitHeader output;
  for (const auto& [field_name_a, field_value] : *parsed) {
    for (const auto& [field_name_b, field_accessor] : kInitHeaderFields) {
      if (field_name_a != field_name_b) {
        continue;
      }
      QUICHE_ASSIGN_OR_RETURN(int64_t value,
                              GetMember<Item::kIntegerType>(field_value));
      if (value < 0) {
        return absl::InvalidArgumentError(
            absl::StrCat("Received negative value for ", field_name_a));
      }
      output.*field_accessor = value;
    }
  }
  return output;
}

absl::StatusOr<std::string> SerializeInitHeader(
    const WebTransportInitHeader& header) {
  std::vector<DictionaryMember> members;
  members.reserve(kInitHeaderFields.size());
  for (const auto& [field_name, field_accessor] : kInitHeaderFields) {
    Item item(static_cast<int64_t>(header.*field_accessor));
    members.push_back(std::make_pair(
        field_name, ParameterizedMember({ParameterizedItem(item, {})}, false,
                                        /*parameters=*/{})));
  }
  std::optional<std::string> result =
      quiche::structured_headers::SerializeDictionary(
          Dictionary(std::move(members)));
  if (!result.has_value()) {
    return absl::InternalError("Failed to serialize the dictionary");
  }
  return *std::move(result);
}

}  // namespace webtransport
