// 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_embedded_file_description_box.h"

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

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "jumbf/box.h"
#include "jumbf/constants.h"
#include "jumbf/internal/intermediate.h"
#include "riegeli/endian/endian_writing.h"

namespace jumbf_internal {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;

TEST(ParseEmbeddedFileDescriptionBoxTest, ParseOkAllToggles) {
  constexpr uint8_t kToggles =
      jumbf::kEfdbToggleFileNamePresent | jumbf::kEfdbToggleExternal;
  // Can't use absl::string_view because the linter does not believe it is
  // null terminated, even when the underlying string definitely is.
  constexpr const char kFakeMediatype[] = "media/MyFormat";
  constexpr const char kFakePath[] = "path/to/some/file";

  const size_t payload_length =
      1 /*toggles*/ + sizeof(kFakeMediatype) + sizeof(kFakePath);
  std::string payload(payload_length, 'A');
  char* cursor = payload.data();
  riegeli::WriteBigEndian<uint8_t>(kToggles, cursor);
  cursor += sizeof(uint8_t);
  memcpy(cursor, kFakeMediatype, sizeof(kFakeMediatype));
  cursor += sizeof(kFakeMediatype);
  memcpy(cursor, kFakePath, sizeof(kFakePath));
  cursor += sizeof(kFakePath);

  const IntermediateBox unwrapped_box{
      .payload = payload,
      .type = jumbf::kEmbeddedFileDescriptionBoxType,
  };

  auto efdb = ParseEmbeddedFileDescriptionBox(unwrapped_box);

  EXPECT_THAT(efdb, IsOkAndHolds(jumbf::EmbeddedFileDescriptionBox{
                        .media_type = kFakeMediatype,
                        .external = true,
                        .file_name = kFakePath,
                    }));
}

TEST(ParseEmbeddedFileDescriptionBoxTest, ParseOkFileNamePresent) {
  constexpr uint8_t kToggles = jumbf::kEfdbToggleFileNamePresent;
  // Can't use absl::string_view because the linter does not believe it is
  // null terminated, even when the underlying string definitely is.
  constexpr const char kFakeMediatype[] = "media/MyFormat";
  constexpr const char kFakePath[] = "path/to/some/file";

  const size_t payload_length =
      1 /*toggles*/ + sizeof(kFakeMediatype) + sizeof(kFakePath);
  std::string payload(payload_length, 'A');
  char* cursor = payload.data();
  riegeli::WriteBigEndian<uint8_t>(kToggles, cursor);
  cursor += sizeof(uint8_t);
  memcpy(cursor, kFakeMediatype, sizeof(kFakeMediatype));
  cursor += sizeof(kFakeMediatype);
  memcpy(cursor, kFakePath, sizeof(kFakePath));
  cursor += sizeof(kFakePath);

  const IntermediateBox unwrapped_box{
      .payload = payload,
      .type = jumbf::kEmbeddedFileDescriptionBoxType,
  };

  auto efdb = ParseEmbeddedFileDescriptionBox(unwrapped_box);

  EXPECT_THAT(efdb, IsOkAndHolds(jumbf::EmbeddedFileDescriptionBox{
                        .media_type = kFakeMediatype,
                        .external = false,
                        .file_name = kFakePath,
                    }));
}

TEST(ParseEmbeddedFileDescriptionBoxTest, ParseOkExternal) {
  constexpr uint8_t kToggles = jumbf::kEfdbToggleExternal;
  // Can't use absl::string_view because the linter does not believe it is
  // null terminated, even when the underlying string definitely is.
  constexpr const char kFakeMediatype[] = "media/MyFormat";

  const size_t payload_length = 1 /*toggles*/ + sizeof(kFakeMediatype);
  std::string payload(payload_length, 'A');
  char* cursor = payload.data();
  riegeli::WriteBigEndian<uint8_t>(kToggles, cursor);
  cursor += sizeof(uint8_t);
  memcpy(cursor, kFakeMediatype, sizeof(kFakeMediatype));
  cursor += sizeof(kFakeMediatype);

  const IntermediateBox unwrapped_box{
      .payload = payload,
      .type = jumbf::kEmbeddedFileDescriptionBoxType,
  };

  auto efdb = ParseEmbeddedFileDescriptionBox(unwrapped_box);

  EXPECT_THAT(efdb, IsOkAndHolds(jumbf::EmbeddedFileDescriptionBox{
                        .media_type = kFakeMediatype,
                        .external = true,
                    }));
}

TEST(ParseEmbeddedFileDescriptionBoxTest, ParseOkNoTogglesl) {
  constexpr uint8_t kToggles = 0;
  constexpr const char kFakeMediatype[] = "media/MyFormat";

  const size_t payload_length = 1 /*toggles*/ + sizeof(kFakeMediatype);
  std::string payload(payload_length, 'A');
  char* cursor = payload.data();
  riegeli::WriteBigEndian<uint8_t>(kToggles, cursor);
  cursor += sizeof(uint8_t);
  memcpy(cursor, kFakeMediatype, sizeof(kFakeMediatype));
  cursor += sizeof(kFakeMediatype);

  const IntermediateBox unwrapped_box{
      .payload = payload,
      .type = jumbf::kEmbeddedFileDescriptionBoxType,
  };

  auto efdb = ParseEmbeddedFileDescriptionBox(unwrapped_box);

  EXPECT_THAT(efdb, IsOkAndHolds(jumbf::EmbeddedFileDescriptionBox{
                        .media_type = kFakeMediatype,
                        .external = false,
                    }));
}

TEST(ParseEmbeddedFileDescriptionBoxTest, WrongTypeFails) {
  constexpr uint8_t kToggles = 0;
  constexpr const char kFakeMediatype[] = "media/MyFormat";

  const size_t payload_length = 1 /*toggles*/ + sizeof(kFakeMediatype);
  std::string payload(payload_length, 'A');
  char* cursor = payload.data();
  riegeli::WriteBigEndian<uint8_t>(kToggles, cursor);
  cursor += sizeof(uint8_t);
  memcpy(cursor, kFakeMediatype, sizeof(kFakeMediatype));
  cursor += sizeof(kFakeMediatype);

  const IntermediateBox unwrapped_box{
      .payload = payload,
      .type = jumbf::kSuperBoxType,
  };

  auto efdb = ParseEmbeddedFileDescriptionBox(unwrapped_box);

  EXPECT_THAT(efdb, StatusIs(absl::StatusCode::kInvalidArgument,
                             "box is not an embedded file description box; got "
                             "type 0x6a756d62 need 0x62666462 ('bfdb')"));
}

TEST(ParseEmbeddedFileDescriptionBoxTest, ExtraDataFails) {
  constexpr uint8_t kToggles = 0;
  constexpr const char kFakeMediatype[] = "media/MyFormat";

  const size_t payload_length = 1 /*toggles*/ + sizeof(kFakeMediatype);
  std::string payload(payload_length, 'A');
  char* cursor = payload.data();
  riegeli::WriteBigEndian<uint8_t>(kToggles, cursor);
  cursor += sizeof(uint8_t);
  memcpy(cursor, kFakeMediatype, sizeof(kFakeMediatype));
  cursor += sizeof(kFakeMediatype);

  payload.append("some extra data nobody asked for");

  const IntermediateBox unwrapped_box{
      .payload = payload,
      .type = jumbf::kEmbeddedFileDescriptionBoxType,
  };

  auto efdb = ParseEmbeddedFileDescriptionBox(unwrapped_box);

  EXPECT_THAT(
      efdb,
      StatusIs(absl::StatusCode::kInvalidArgument,
               "excess data in embedded file description box payload; after "
               "parsing complete, valid payload, 32 bytes were remaining"));
}

}  // namespace
}  // namespace jumbf_internal
