// 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 "quic/load_balancer/load_balancer_server_id.h"
#include "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.
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_
