// Copyright (c) 2022 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.

#ifndef QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_MAP_H_
#define QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_MAP_H_

#include "absl/container/flat_hash_map.h"
#include "quiche/quic/load_balancer/load_balancer_server_id.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"

namespace quic {

// This class wraps an absl::flat_hash_map which associates server IDs to an
// arbitrary type T. It validates that all server ids are of the same fixed
// length. This might be used by a load balancer to connect a server ID with a
// pool member data structure.
template <typename T>
class QUIC_EXPORT_PRIVATE LoadBalancerServerIdMap {
 public:
  // Returns a newly created pool for server IDs of length |server_id_len|, or
  // nullptr if |server_id_len| is invalid.
  static std::shared_ptr<LoadBalancerServerIdMap> Create(
      const uint8_t server_id_len);

  // Returns the entry associated with |server_id|, if present. For small |T|,
  // use Lookup. For large |T|, use LookupNoCopy.
  absl::optional<const T> Lookup(const LoadBalancerServerId server_id) const;
  const T* LookupNoCopy(const LoadBalancerServerId server_id) const;

  // Updates the table so that |value| is associated with |server_id|. Sets
  // QUIC_BUG if the length is incorrect for this map.
  void AddOrReplace(const LoadBalancerServerId server_id, T value);

  // Removes the entry associated with |server_id|.
  void Erase(const LoadBalancerServerId server_id) {
    server_id_table_.erase(server_id);
  }

  uint8_t server_id_len() const { return server_id_len_; }

 private:
  LoadBalancerServerIdMap(uint8_t server_id_len)
      : server_id_len_(server_id_len) {}

  const uint8_t server_id_len_;  // All server IDs must be of this length.
  absl::flat_hash_map<LoadBalancerServerId, T> server_id_table_;
};

template <typename T>
std::shared_ptr<LoadBalancerServerIdMap<T>> LoadBalancerServerIdMap<T>::Create(
    const uint8_t server_id_len) {
  if (server_id_len == 0 || server_id_len > kLoadBalancerMaxServerIdLen) {
    QUIC_BUG(quic_bug_434893339_01)
        << "Tried to configure map with server ID length "
        << static_cast<int>(server_id_len);
    return nullptr;
  }
  return std::make_shared<LoadBalancerServerIdMap<T>>(
      LoadBalancerServerIdMap(server_id_len));
}

template <typename T>
absl::optional<const T> LoadBalancerServerIdMap<T>::Lookup(
    const LoadBalancerServerId server_id) const {
  if (server_id.length() != server_id_len_) {
    QUIC_BUG(quic_bug_434893339_02)
        << "Lookup with a " << static_cast<int>(server_id.length())
        << " byte server ID, map requires " << static_cast<int>(server_id_len_);
    return absl::optional<T>();
  }
  auto it = server_id_table_.find(server_id);
  return (it != server_id_table_.end()) ? it->second
                                        : absl::optional<const T>();
}

template <typename T>
const T* LoadBalancerServerIdMap<T>::LookupNoCopy(
    const LoadBalancerServerId server_id) const {
  if (server_id.length() != server_id_len_) {
    QUIC_BUG(quic_bug_434893339_02)
        << "Lookup with a " << static_cast<int>(server_id.length())
        << " byte server ID, map requires " << static_cast<int>(server_id_len_);
    return nullptr;
  }
  auto it = server_id_table_.find(server_id);
  return (it != server_id_table_.end()) ? &it->second : nullptr;
}

template <typename T>
void LoadBalancerServerIdMap<T>::AddOrReplace(
    const LoadBalancerServerId server_id, T value) {
  if (server_id.length() == server_id_len_) {
    server_id_table_[server_id] = value;
  } else {
    QUIC_BUG(quic_bug_434893339_03)
        << "Server ID of " << static_cast<int>(server_id.length())
        << " bytes; this map requires " << static_cast<int>(server_id_len_);
  }
}

}  // namespace quic

#endif  // QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_MAP_H_
