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

#include <sys/types.h>

#include <cstddef>
#include <cstdint>
#include <limits>
#include <string>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"  // IWYU pragma: keep
#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/encode_params.h"
#include "jumbf/internal/serialization_utils.h"
#include "jumbf/test_utils.h"
#include "riegeli/base/chain.h"
#include "riegeli/base/maker.h"
#include "riegeli/bytes/chain_backward_writer.h"
#include "riegeli/bytes/position_shifting_backward_writer.h"

namespace jumbf {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::jumbf_internal::ConsumeInteger;
using ::testing::Eq;
using ::testing::IsEmpty;

TEST(EncodePaddingBoxTest, EncodesPaddingBox) {
  constexpr uint64_t kPaddingSize = 7;
  constexpr size_t kExpectedOutputSize =
      sizeof(uint32_t) /*LBox*/ + sizeof(uint32_t) /*TBox*/ + kPaddingSize;

  riegeli::ChainBackwardWriter writer;
  ABSL_ASSERT_OK(EncodePaddingBox(7, &writer));
  writer.Close();
  absl::string_view result_view = writer.dest().Flatten();

  EXPECT_THAT(writer.pos(), kExpectedOutputSize);
  // LBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(kExpectedOutputSize));
  // TBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds('free'));
  EXPECT_THAT(jumbf_internal::ConsumeBytes(&result_view, kPaddingSize),
              IsOkAndHolds(std::string("\0\0\0\0\0\0\0\0", 7)));
  EXPECT_THAT(result_view, IsEmpty());
}

TEST(EncodeContentBoxTest, EncodesContentBox) {
  constexpr absl::string_view kPayload = R"(I am payload!)";
  constexpr uint32_t kTbox = 0xfeedbabe;
  constexpr size_t kExpectedOutputSize =
      sizeof(uint32_t) /*LBox*/ + sizeof(uint32_t) /*TBox*/ + kPayload.length();
  // Simulating content already written in superbox
  constexpr size_t kTotalBytesInitial = 5280;

  riegeli::PositionShiftingBackwardWriter writer(
      riegeli::Maker<riegeli::ChainBackwardWriter>(),
      riegeli::PositionShiftingBackwardWriterBase::Options().set_base_pos(
          kTotalBytesInitial));
  ABSL_ASSERT_OK(EncodeContentBox(kTbox, CordFromConstexpr(kPayload), &writer));
  writer.Close();
  absl::string_view result_view = writer.dest().dest().Flatten();

  EXPECT_THAT(writer.pos(), Eq(kTotalBytesInitial + kExpectedOutputSize));
  // LBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(kExpectedOutputSize));
  // TBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(kTbox));
  EXPECT_THAT(jumbf_internal::ConsumeBytes(&result_view, kPayload.length()),
              IsOkAndHolds(kPayload));
  EXPECT_THAT(result_view, IsEmpty());
}

TEST(EncodeDescriptionBoxTest, DefaultOptions) {
  constexpr size_t kExpectedOutputSize = 25;
  // Simulating content already written in superbox
  constexpr size_t kTotalBytesInitial = 0xf00dbabe;

  riegeli::PositionShiftingBackwardWriter writer(
      riegeli::Maker<riegeli::ChainBackwardWriter>(),
      riegeli::PositionShiftingBackwardWriterBase::Options().set_base_pos(
          kTotalBytesInitial));
  ABSL_ASSERT_OK(
      EncodeDescriptionBox(kCborBoxTypeUuid, DescriptionBoxOptions{}, &writer));

  ASSERT_TRUE(writer.Close());
  absl::string_view result_view = writer.dest().dest().Flatten();

  EXPECT_THAT(writer.pos(), Eq(kExpectedOutputSize + 0xf00dbabe));

  // LBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(kExpectedOutputSize));
  // TBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(kDescriptionBoxType));

  // Type UUID
  EXPECT_THAT(jumbf_internal::ConsumeBytes(&result_view, 16),
              IsOkAndHolds(kCborBoxTypeUuid.ToProtoBytes()));
  // Toggles
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint8_t>(&result_view),
              IsOkAndHolds(0));

  EXPECT_THAT(result_view, IsEmpty());
}

TEST(EncodeDescriptionBoxTest, HasLabel) {
  constexpr absl::string_view kLabel = "mylabel";
  constexpr size_t kExpectedOutputSize =
      4 /*lbox*/ + 4 /*tbox*/ + 16 /*type UUID*/ + 1 /*toggles*/ +
      kLabel.length() + 1 /*label NUL terminator*/;
  // Simulating content already written in superbox
  constexpr size_t kTotalBytesInitial = 0xdeadbeef;

  riegeli::PositionShiftingBackwardWriter writer(
      riegeli::Maker<riegeli::ChainBackwardWriter>(),
      riegeli::PositionShiftingBackwardWriterBase::Options().set_base_pos(
          kTotalBytesInitial));
  ABSL_ASSERT_OK(EncodeDescriptionBox(kCborBoxTypeUuid,
                                      DescriptionBoxOptions{
                                          .label = CordFromConstexpr(kLabel),
                                      },
                                      &writer));

  ASSERT_TRUE(writer.Close());
  absl::string_view result_view = writer.dest().dest().Flatten();

  EXPECT_THAT(writer.pos(), Eq(kExpectedOutputSize + kTotalBytesInitial));

  // LBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(kExpectedOutputSize));
  // TBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(kDescriptionBoxType));

  // Type UUID
  EXPECT_THAT(jumbf_internal::ConsumeBytes(&result_view, 16),
              IsOkAndHolds(kCborBoxTypeUuid.ToProtoBytes()));
  // Toggles
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint8_t>(&result_view),
              IsOkAndHolds(kDescriptionToggleLabelPresent |
                           kDescriptionToggleRequestable));
  // Label
  EXPECT_THAT(jumbf_internal::ConsumeNullTerminated(&result_view),
              IsOkAndHolds("mylabel"));

  EXPECT_THAT(result_view, IsEmpty());
}

TEST(EncodeDescriptionBoxTest, HasPrivateContent) {
  constexpr absl::string_view kPrivateContent =
      "Hi, I'm not actually JUMBF data but for this test it doesn't matter.";
  constexpr size_t kExpectedOutputSize = 4 /*lbox*/ + 4 /*tbox*/ +
                                         16 /*type UUID*/ + 1 /*toggles*/ +
                                         kPrivateContent.length();
  // Simulating content already written in superbox
  constexpr size_t kTotalBytesInitial = 0xbaadf00d;

  riegeli::PositionShiftingBackwardWriter writer(
      riegeli::Maker<riegeli::ChainBackwardWriter>(),
      riegeli::PositionShiftingBackwardWriterBase::Options().set_base_pos(
          kTotalBytesInitial));
  ABSL_ASSERT_OK(EncodeDescriptionBox(
      kCborBoxTypeUuid,
      DescriptionBoxOptions{
          .requestable_iff_label = false,
          .private_content = CordFromConstexpr(kPrivateContent),
      },
      &writer));

  ASSERT_TRUE(writer.Close());
  absl::string_view result_view = writer.dest().dest().Flatten();

  EXPECT_THAT(writer.pos(), Eq(kExpectedOutputSize + kTotalBytesInitial));

  // LBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(kExpectedOutputSize));
  // TBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(kDescriptionBoxType));

  // Type UUID
  EXPECT_THAT(jumbf_internal::ConsumeBytes(&result_view, 16),
              IsOkAndHolds(kCborBoxTypeUuid.ToProtoBytes()));
  // Toggles
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint8_t>(&result_view),
              IsOkAndHolds(kDescriptionTogglePrivatePresent));
  // Private content
  EXPECT_THAT(
      jumbf_internal::ConsumeBytes(&result_view, kPrivateContent.length()),
      IsOkAndHolds(kPrivateContent));

  EXPECT_THAT(result_view, IsEmpty());
}

TEST(EncodeDescriptionBoxTest, HasLabelNotRequestable) {
  constexpr size_t kExpectedOutputSize = 33;
  constexpr absl::string_view kLabel = "mylabel";
  // Simulating content already written in superbox
  constexpr size_t kTotalBytesInitial = 0xdefec8ed;

  riegeli::PositionShiftingBackwardWriter writer(
      riegeli::Maker<riegeli::ChainBackwardWriter>(),
      riegeli::PositionShiftingBackwardWriterBase::Options().set_base_pos(
          kTotalBytesInitial));
  ABSL_ASSERT_OK(EncodeDescriptionBox(kCborBoxTypeUuid,
                                      DescriptionBoxOptions{
                                          .requestable_iff_label = false,
                                          .label = CordFromConstexpr(kLabel),
                                      },
                                      &writer));

  EXPECT_THAT(writer.pos(), Eq(kExpectedOutputSize + kTotalBytesInitial));

  ASSERT_TRUE(writer.Close());
  absl::string_view result_view = writer.dest().dest().Flatten();

  // LBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(kExpectedOutputSize));
  // TBox
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(kDescriptionBoxType));

  // Type UUID
  EXPECT_THAT(jumbf_internal::ConsumeBytes(&result_view, 16),
              IsOkAndHolds(kCborBoxTypeUuid.ToProtoBytes()));
  // Toggles
  EXPECT_THAT(jumbf_internal::ConsumeInteger<uint8_t>(&result_view),
              IsOkAndHolds(kDescriptionToggleLabelPresent));
  // Label
  EXPECT_THAT(jumbf_internal::ConsumeNullTerminated(&result_view),
              IsOkAndHolds("mylabel"));

  EXPECT_THAT(result_view, IsEmpty());
}

TEST(EncodeBoxHeaderTest, LBox) {
  // Fake value, pretending we already wrote some content to `writer`.
  constexpr size_t kPayloadSize = 10;

  riegeli::PositionShiftingBackwardWriter writer(
      riegeli::Maker<riegeli::ChainBackwardWriter>(),
      riegeli::PositionShiftingBackwardWriterBase::Options().set_base_pos(
          kPayloadSize));
  ABSL_EXPECT_OK(EncodeBoxHeader(kPayloadSize, 0xdeadbeef, &writer));

  ASSERT_TRUE(writer.Close());
  absl::string_view result_view = writer.dest().dest().Flatten();

  // Should have been updated to include the (fake) content plus LBox and TBox.
  EXPECT_THAT(writer.pos(), Eq(kPayloadSize + 8));

  // LBox
  EXPECT_THAT(ConsumeInteger<uint32_t>(&result_view),
              IsOkAndHolds(writer.pos()));
  // TBox
  EXPECT_THAT(ConsumeInteger<uint32_t>(&result_view), IsOkAndHolds(0xdeadbeef));
  EXPECT_THAT(result_view, IsEmpty());
}

TEST(EncodeBoxHeaderTest, XLBox) {
  // Fake value, pretending we already wrote some content to `writer`.
  constexpr size_t kPayloadSize =
      static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 10;

  riegeli::PositionShiftingBackwardWriter writer(
      riegeli::Maker<riegeli::ChainBackwardWriter>(),
      riegeli::PositionShiftingBackwardWriterBase::Options().set_base_pos(
          kPayloadSize));
  ABSL_EXPECT_OK(EncodeBoxHeader(kPayloadSize, 0xdeadbeef, &writer));

  ASSERT_TRUE(writer.Close());
  absl::string_view result_view = writer.dest().dest().Flatten();

  // Should have been updated to include the (fake) content plus LBox, TBox, and
  // XLBox.
  EXPECT_THAT(writer.pos(), Eq(kPayloadSize + 16));

  // LBox
  EXPECT_THAT(ConsumeInteger<uint32_t>(&result_view), IsOkAndHolds(1));
  // TBox
  EXPECT_THAT(ConsumeInteger<uint32_t>(&result_view), IsOkAndHolds(0xdeadbeef));
  // XLBox
  EXPECT_THAT(ConsumeInteger<uint64_t>(&result_view),
              IsOkAndHolds(writer.pos()));
  EXPECT_THAT(result_view, IsEmpty());
}

TEST(EncodeBoxHeaderTest, XLBoxPayloadExceedsMaxBoxSize) {
  // Fake value, pretending we already wrote some content to `writer`.
  constexpr size_t kPayloadSize = std::numeric_limits<size_t>::max();

  riegeli::PositionShiftingBackwardWriter writer(
      riegeli::Maker<riegeli::ChainBackwardWriter>(),
      riegeli::PositionShiftingBackwardWriterBase::Options().set_base_pos(
          kPayloadSize));
  EXPECT_THAT(
      EncodeBoxHeader(kPayloadSize, 0xdeadbeef, &writer),
      StatusIs(absl::StatusCode::kOutOfRange, "maximum box size exceeded"));
}

}  // namespace
}  // namespace jumbf
