// Copyright 2024 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/quic/moqt/moqt_messages.h"

#include <optional>
#include <vector>

#include "absl/hash/hash.h"
#include "absl/strings/string_view.h"
#include "quiche/common/platform/api/quiche_expect_bug.h"
#include "quiche/common/platform/api/quiche_test.h"

namespace moqt::test {
namespace {

TEST(MoqtMessagesTest, TrackNamespaceConstructors) {
  TrackNamespace name1({"foo", "bar"});
  std::vector<absl::string_view> list = {"foo", "bar"};
  TrackNamespace name2(list);
  EXPECT_EQ(name1, name2);
  EXPECT_EQ(absl::HashOf(name1), absl::HashOf(name2));
}

TEST(MoqtMessagesTest, TrackNamespaceOrder) {
  TrackNamespace name1({"a", "b"});
  TrackNamespace name2({"a", "b", "c"});
  TrackNamespace name3({"b", "a"});
  EXPECT_LT(name1, name2);
  EXPECT_LT(name2, name3);
  EXPECT_LT(name1, name3);
}

TEST(MoqtMessagesTest, TrackNamespaceInNamespace) {
  TrackNamespace name1({"a", "b"});
  TrackNamespace name2({"a", "b", "c"});
  TrackNamespace name3({"d", "b"});
  EXPECT_TRUE(name2.InNamespace(name1));
  EXPECT_FALSE(name1.InNamespace(name2));
  EXPECT_TRUE(name1.InNamespace(name1));
  EXPECT_FALSE(name2.InNamespace(name3));
}

TEST(MoqtMessagesTest, TrackNamespaceToString) {
  TrackNamespace name1({"a", "b"});
  EXPECT_EQ(name1.ToString(), R"({"a"::"b"})");

  TrackNamespace name2({"\xff", "\x61"});
  EXPECT_EQ(name2.ToString(), R"({"\xff"::"a"})");
}

TEST(MoqtMessagesTest, FullTrackNameToString) {
  FullTrackName name1(TrackNamespace{"a", "b"}, "c");
  EXPECT_EQ(name1.ToString(), R"({"a"::"b"}::c)");
}

TEST(MoqtMessagesTest, TooManyNamespaceElements) {
  // 32 elements work.
  TrackNamespace name1({"a", "b", "c",  "d",  "e",  "f",  "g",  "h",
                        "i", "j", "k",  "l",  "m",  "n",  "o",  "p",
                        "q", "r", "s",  "t",  "u",  "v",  "w",  "x",
                        "y", "z", "aa", "bb", "cc", "dd", "ee", "ff"});
  EXPECT_TRUE(name1.IsValid());
  EXPECT_QUICHE_BUG(name1.AddElement("a"),
                    "Constructing a namespace that is too large.");
  EXPECT_EQ(name1.number_of_elements(), kMaxNamespaceElements);

  // 33 elements fail,
  TrackNamespace name2;
  EXPECT_QUICHE_BUG(
      name2 = TrackNamespace({"a",  "b",  "c",  "d",  "e",  "f", "g", "h", "i",
                              "j",  "k",  "l",  "m",  "n",  "o", "p", "q", "r",
                              "s",  "t",  "u",  "v",  "w",  "x", "y", "z", "aa",
                              "bb", "cc", "dd", "ee", "ff", "gg"}),
      "Constructing a namespace that is too large.");
  EXPECT_FALSE(name2.IsValid());
}

TEST(MoqtMessagesTest, FullTrackNameTooLong) {
  char raw_name[kMaxFullTrackNameSize + 1];
  absl::string_view track_namespace(raw_name, kMaxFullTrackNameSize);
  // Adding an element takes it over the length limit.
  TrackNamespace max_length_namespace({track_namespace});
  EXPECT_TRUE(max_length_namespace.IsValid());
  EXPECT_QUICHE_BUG(max_length_namespace.AddElement("f"),
                    "Constructing a namespace that is too large.");
  // Constructing a FullTrackName where the name brings it over the length
  // limit.
  EXPECT_QUICHE_BUG(FullTrackName(max_length_namespace, "f"),
                    "Constructing a Full Track Name that is too large.");
  // The namespace is too long by itself..
  absl::string_view big_namespace(raw_name, kMaxFullTrackNameSize + 1);
  EXPECT_QUICHE_BUG(TrackNamespace({big_namespace}),
                    "Constructing a namespace that is too large.");
}

TEST(MoqtMessagesTest, MoqtDatagramType) {
  for (bool payload : {false, true}) {
    for (bool extension : {false, true}) {
      for (bool end_of_group : {false, true}) {
        for (bool zero_object_id : {false, true}) {
          MoqtDatagramType type(payload, extension, end_of_group,
                                zero_object_id);
          EXPECT_EQ(type.has_status(),
                    !payload && (!end_of_group || !zero_object_id));
          EXPECT_EQ(type.has_extension(), extension);
          EXPECT_EQ(type.end_of_group(),
                    end_of_group && (payload || zero_object_id));
          EXPECT_EQ(type.has_object_id(),
                    !zero_object_id || (!payload && !end_of_group));
          // The constructor should always produce a valid value.
          std::optional<MoqtDatagramType> from_value =
              MoqtDatagramType::FromValue(type.value());
          EXPECT_TRUE(from_value.has_value() && type == *from_value);
        }
      }
    }
  }
}

}  // namespace
}  // namespace moqt::test
