// 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.GetIfInteger();
  } else if constexpr (kExpectedType == Item::kStringType) {
    return 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.Type()), " instead"));
  }
  return std::move(*ptr);
}

template <Item::ItemType kExpectedType>
auto GetMember(auto&& member) {
  auto item = member.GetWithParamsIfItem();
  using ReturnType = decltype(GetItem<kExpectedType>(item->first));

  if (!item.has_value()) {
    return ReturnType(absl::InvalidArgumentError(absl::StrCat(
        "Expected all members to be of type", ItemTypeToString(kExpectedType),
        ", found a nested list instead")));
  }
  return GetItem<kExpectedType>(item->first);
}

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.emplace_back(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->item);
}

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) {
    members.emplace_back(field_name,
                         Item(static_cast<int64_t>(header.*field_accessor)));
  }
  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
