// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "jumbf/internal/parse_description_box.h"

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/strings/string_view.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "jumbf/constants.h"
#include "jumbf/internal/intermediate.h"
#include "jumbf/test_utils.h"
#include "riegeli/endian/endian_writing.h"
#include "uuid/uuid.h"

namespace jumbf_internal {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::credentio::Uuid;
using ::jumbf::SerializeUuid;

constexpr absl::string_view kFakeUuid =
    R"(deadbeef-f00d-babe-b4df-00d528013378)";

TEST(ParseDescriptionBoxTest, ParseOkNoToggles) {
  // Can't use absl::string_view because the compiler warns against assuming it
  // is null terminated, even when it truly is null terminated.
  const size_t description_content_length = /*uuid*/ 16 + /*toggles*/ 1;
  std::string fake_description_contents(description_content_length, 'A');
  char* content_cursor = fake_description_contents.data();

  SerializeUuid(&content_cursor, Uuid::FromStringOrDie(kFakeUuid));
  riegeli::WriteBigEndian<uint8_t>(0, content_cursor);
  content_cursor += sizeof(uint8_t);

  IntermediateBox unwrapped_description{
      .payload = fake_description_contents,
      .type = jumbf::kDescriptionBoxType,
  };

  EXPECT_THAT(ParseDescriptionBox(unwrapped_description),
              IsOkAndHolds(IntermediateDescriptionBox{
                  .type_uuid = Uuid::FromStringOrDie(kFakeUuid)}));
}

TEST(ParseDescriptionBoxTest, InvalidPayloadSize) {
  // A fuzzer crafted this box, with a payload that is too short.
  IntermediateBox box = {
      .payload = "",
      .serialized = absl::string_view("\x00\x00\x00\x08jumd", 8),
      .type = 1786080612,
      .implicit_length = false};

  EXPECT_THAT(ParseDescriptionBox(box),
              StatusIs(absl::StatusCode::kOutOfRange));
}

TEST(ParseDescriptionBoxTest, ParseOkAllToggles) {
  // Can't use absl::string_view because the compiler warns against assuming it
  // is null terminated, even when it truly is null terminated.
  constexpr char kFakeLabel[] = "fakelabel";
  constexpr uint32_t kFakeId = 0xB33FD00D;
  const std::string fake_hash(32, 'X');
  constexpr absl::string_view kPrivatePayload =
      R"(The format of this data is unimportant for this test case.)";
  const std::string private_box = jumbf::WrapBox(kPrivatePayload, 12345);
  const size_t description_content_length =
      /*uuid*/ 16 + /*toggles*/ 1 + strlen(kFakeLabel) +
      /*label null terminator*/ 1 + /*id*/ 4 + fake_hash.length() +
      private_box.length();
  std::string fake_description_contents(description_content_length, 'A');
  char* content_cursor = fake_description_contents.data();

  SerializeUuid(&content_cursor, Uuid::FromStringOrDie(kFakeUuid));
  uint8_t toggles = jumbf::kDescriptionToggleRequestable |
                    jumbf::kDescriptionToggleLabelPresent |
                    jumbf::kDescriptionToggleIdPresent |
                    jumbf::kDescriptionToggleHashPresent |
                    jumbf::kDescriptionTogglePrivatePresent;
  riegeli::WriteBigEndian<uint8_t>(toggles, content_cursor);
  content_cursor += sizeof(uint8_t);
  memcpy(content_cursor, kFakeLabel, strlen(kFakeLabel) + 1);
  content_cursor += strlen(kFakeLabel) + 1;
  riegeli::WriteBigEndian<uint32_t>(kFakeId, content_cursor);
  content_cursor += sizeof(uint32_t);
  memcpy(content_cursor, fake_hash.data(), 32);
  content_cursor += 32;
  memcpy(content_cursor, private_box.data(), private_box.length());

  IntermediateBox unwrapped_description{
      .payload = fake_description_contents,
      .type = jumbf::kDescriptionBoxType,
  };

  EXPECT_THAT(ParseDescriptionBox(unwrapped_description),
              IsOkAndHolds(IntermediateDescriptionBox{
                  .type_uuid = Uuid::FromStringOrDie(kFakeUuid),
                  .requestable = true,
                  .label = kFakeLabel,
                  .id = kFakeId,
                  .hash = fake_hash,
                  .private_box =
                      IntermediateBox{
                          .payload = kPrivatePayload,
                          .serialized = private_box,
                          .type = 12345,
                      },
              }));
}

TEST(ParseDescriptionBoxTest, RequestableNoLabelFails) {
  const size_t description_content_length = /*uuid*/ 16 + /*toggles*/ 1;
  std::string fake_description_contents(description_content_length, 'A');
  char* content_cursor = fake_description_contents.data();

  SerializeUuid(&content_cursor, Uuid::FromStringOrDie(kFakeUuid));
  riegeli::WriteBigEndian<uint8_t>(jumbf::kDescriptionToggleRequestable,
                                   content_cursor);
  content_cursor += sizeof(uint8_t);

  IntermediateBox unwrapped_description{
      .payload = fake_description_contents,
      .type = jumbf::kDescriptionBoxType,
  };

  EXPECT_THAT(ParseDescriptionBox(unwrapped_description),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       "requestable bit is set, but box does not have a label; "
                       "if a box is requestable the label is required"));
}

TEST(ParseDescriptionBoxTest, ParseOkWithLabel) {
  // Can't use absl::string_view because the compiler warns against assuming it
  // is null terminated, even when it truly is null terminated.
  constexpr char kFakeLabel[] = "fakelabel";
  const size_t description_content_length = /*uuid*/ 16 + /*toggles*/ 1 +
                                            strlen(kFakeLabel) +
                                            /*label null terminator*/ 1;
  std::string fake_description_contents(description_content_length, 'A');
  char* content_cursor = fake_description_contents.data();

  SerializeUuid(&content_cursor, Uuid::FromStringOrDie(kFakeUuid));
  riegeli::WriteBigEndian<uint8_t>(jumbf::kDescriptionToggleLabelPresent,
                                   content_cursor);
  content_cursor += sizeof(uint8_t);
  memcpy(content_cursor, kFakeLabel, strlen(kFakeLabel) + 1);
  content_cursor += strlen(kFakeLabel) + 1;

  IntermediateBox unwrapped_description{
      .payload = fake_description_contents,
      .type = jumbf::kDescriptionBoxType,
  };

  EXPECT_THAT(
      ParseDescriptionBox(unwrapped_description),
      IsOkAndHolds(IntermediateDescriptionBox{
          .type_uuid = Uuid::FromStringOrDie(kFakeUuid), .label = kFakeLabel}));
}

TEST(ParseDescriptionBoxTest, ParseOkWithId) {
  constexpr uint32_t kFakeId = 0xB33FD00D;
  const size_t description_content_length =
      /*uuid*/ 16 + /*toggles*/ 1 + /*id*/ 4;
  std::string fake_description_contents(description_content_length, 'A');
  char* content_cursor = fake_description_contents.data();

  SerializeUuid(&content_cursor, Uuid::FromStringOrDie(kFakeUuid));
  riegeli::WriteBigEndian<uint8_t>(jumbf::kDescriptionToggleIdPresent,
                                   content_cursor);
  content_cursor += sizeof(uint8_t);
  riegeli::WriteBigEndian<uint32_t>(kFakeId, content_cursor);
  content_cursor += sizeof(uint32_t);

  IntermediateBox unwrapped_description{
      .payload = fake_description_contents,
      .type = jumbf::kDescriptionBoxType,
  };

  EXPECT_THAT(
      ParseDescriptionBox(unwrapped_description),
      IsOkAndHolds(IntermediateDescriptionBox{
          .type_uuid = Uuid::FromStringOrDie(kFakeUuid), .id = kFakeId}));
}

TEST(ParseDescriptionBoxTest, ParseOkWithHash) {
  const std::string fake_hash(32, 'X');
  const size_t description_content_length =
      /*uuid*/ 16 + /*toggles*/ 1 + fake_hash.length();
  std::string fake_description_contents(description_content_length, 'A');
  char* content_cursor = fake_description_contents.data();

  SerializeUuid(&content_cursor, Uuid::FromStringOrDie(kFakeUuid));
  riegeli::WriteBigEndian<uint8_t>(jumbf::kDescriptionToggleHashPresent,
                                   content_cursor);
  content_cursor += sizeof(uint8_t);
  memcpy(content_cursor, fake_hash.data(), 32);

  IntermediateBox unwrapped_description{
      .payload = fake_description_contents,
      .type = jumbf::kDescriptionBoxType,
  };

  EXPECT_THAT(
      ParseDescriptionBox(unwrapped_description),
      IsOkAndHolds(IntermediateDescriptionBox{
          .type_uuid = Uuid::FromStringOrDie(kFakeUuid), .hash = fake_hash}));
}

TEST(ParseDescriptionBoxTest, ParseOkWithPrivate) {
  constexpr absl::string_view kPrivatePayload =
      R"(The format of this data is unimportant for this test case.)";
  const std::string private_box = jumbf::WrapBox(kPrivatePayload, 12345);
  const size_t description_content_length =
      /*uuid*/ 16 + /*toggles*/ 1 + private_box.length();
  std::string fake_description_contents(description_content_length, 'A');
  char* content_cursor = fake_description_contents.data();

  SerializeUuid(&content_cursor, Uuid::FromStringOrDie(kFakeUuid));
  riegeli::WriteBigEndian<uint8_t>(jumbf::kDescriptionTogglePrivatePresent,
                                   content_cursor);
  content_cursor += sizeof(uint8_t);
  memcpy(content_cursor, private_box.data(), private_box.length());

  IntermediateBox unwrapped_description{
      .payload = fake_description_contents,
      .type = jumbf::kDescriptionBoxType,
  };

  EXPECT_THAT(ParseDescriptionBox(unwrapped_description),
              IsOkAndHolds(IntermediateDescriptionBox{
                  .type_uuid = Uuid::FromStringOrDie(kFakeUuid),
                  .private_box =
                      IntermediateBox{
                          .payload = kPrivatePayload,
                          .serialized = private_box,
                          .type = 12345,
                      },
              }));
}

TEST(ParseDescriptionBoxTest, WrongTypeFails) {
  // Can't use absl::string_view because the compiler warns against assuming it
  // is null terminated, even when it truly is null terminated.
  const size_t description_content_length = /*uuid*/ 16 + /*toggles*/ 1;
  std::string fake_description_contents(description_content_length, 'A');
  char* content_cursor = fake_description_contents.data();

  SerializeUuid(&content_cursor, Uuid::FromStringOrDie(kFakeUuid));
  riegeli::WriteBigEndian<uint8_t>(0, content_cursor);
  content_cursor += sizeof(uint8_t);

  IntermediateBox unwrapped_description{
      .payload = fake_description_contents,
      .type = jumbf::kSuperBoxType,
  };

  EXPECT_THAT(ParseDescriptionBox(unwrapped_description),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       "box is not a description box; got type 0x6a756d62 need "
                       "0x6a756d64 ('jumd')"));
}

TEST(ParseDescriptionBoxTest, UnterminatedLabelFails) {
  // Can't use absl::string_view because the compiler warns against assuming it
  // is null terminated, even when it truly is null terminated.
  constexpr char kFakeLabel[] = "fakelabel";
  const size_t description_content_length =
      /*uuid*/ 16 + /*toggles*/ 1 + strlen(kFakeLabel);
  std::string fake_description_contents(description_content_length, 'A');
  char* content_cursor = fake_description_contents.data();

  SerializeUuid(&content_cursor, Uuid::FromStringOrDie(kFakeUuid));
  riegeli::WriteBigEndian<uint8_t>(jumbf::kDescriptionToggleLabelPresent,
                                   content_cursor);
  content_cursor += sizeof(uint8_t);
  // Intentionally not copying null terminator.
  memcpy(content_cursor, kFakeLabel, strlen(kFakeLabel));

  IntermediateBox unwrapped_description{
      .payload = fake_description_contents,
      .type = jumbf::kDescriptionBoxType,
  };

  EXPECT_THAT(ParseDescriptionBox(unwrapped_description),
              StatusIs(absl::StatusCode::kOutOfRange,
                       "cannot read label: ran out of input bytes before "
                       "reading null terminator"));
}

}  // namespace
}  // namespace jumbf_internal
