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

#include <cstdint>
#include <limits>
#include <string>
#include <type_traits>

#include "absl/functional/function_ref.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "riegeli/bytes/string_reader.h"
#include "riegeli/bytes/string_writer.h"
#include "testing/test_string_utils.h"

namespace credentio {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::testing::HasSubstr;

template <typename T>
using CreateStringFunction = absl::FunctionRef<std::string(T)>;

template <typename T>
absl::StatusOr<CreateStringFunction<T>> GetCreateStringFunction() {
  if (!std::is_unsigned_v<T>) {
    return absl::InvalidArgumentError("Type must be unsigned");
  }

  switch (sizeof(T)) {
    case 1:
      return credentio_testing::Uint8Str;
    case 2:
      return credentio_testing::Uint16Str;
    case 4:
      return credentio_testing::Uint32Str;
    case 8:
      return credentio_testing::Uint64Str;
  }

  return absl::InvalidArgumentError("Unsupported type size");
}

template <typename T>
using CopyBigEndianTests = testing::Test;

TYPED_TEST_SUITE_P(CopyBigEndianTests);

TYPED_TEST_P(CopyBigEndianTests, FailsWhenSourceClosed) {
  std::string source_str = "";
  riegeli::StringReader<> source_reader(source_str);

  std::string result;
  riegeli::StringWriter<> destination(&result);

  source_reader.Close();

  EXPECT_THAT(CopyBigEndian<TypeParam>(source_reader, destination, 0),
              StatusIs(absl::StatusCode::kFailedPrecondition,
                       HasSubstr("Object closed")));

  destination.Close();
  EXPECT_EQ(result, "");
}

TYPED_TEST_P(CopyBigEndianTests, FailsWhenDestinationClosed) {
  auto create_string = GetCreateStringFunction<TypeParam>();
  ASSERT_TRUE(create_string.ok());

  std::string source_str = (*create_string)(10);
  riegeli::StringReader<> source_reader(source_str);

  std::string result;
  riegeli::StringWriter<> destination(&result);

  destination.Close();

  EXPECT_THAT(CopyBigEndian<TypeParam>(source_reader, destination, 0),
              StatusIs(absl::StatusCode::kFailedPrecondition,
                       HasSubstr("Object closed")));
}

TYPED_TEST_P(CopyBigEndianTests, FailsWhenNoSource) {
  std::string source_str = "";
  riegeli::StringReader<> source_reader(source_str);

  std::string result;
  riegeli::StringWriter<> destination(&result);

  EXPECT_THAT(
      CopyBigEndian<TypeParam>(source_reader, destination, 0),
      StatusIs(absl::StatusCode::kDataLoss, HasSubstr("Failed to read")));

  destination.Close();
  EXPECT_EQ(result, "");
}

TYPED_TEST_P(CopyBigEndianTests, FailsWhenTooLarge) {
  auto create_string = GetCreateStringFunction<TypeParam>();
  ASSERT_TRUE(create_string.ok());

  std::string source_str =
      (*create_string)(std::numeric_limits<TypeParam>().max() - 10);
  riegeli::StringReader<> source_reader(source_str);

  std::string result;
  riegeli::StringWriter<> destination(&result);

  EXPECT_THAT(CopyBigEndian<TypeParam>(source_reader, destination,
                                       std::numeric_limits<int64_t>().max()),
              StatusIs(absl::StatusCode::kDataLoss,
                       HasSubstr("adjusted offset is too large")));

  destination.Close();
  EXPECT_EQ(result, "");
}

TYPED_TEST_P(CopyBigEndianTests, Succeeds) {
  auto create_string = GetCreateStringFunction<TypeParam>();
  ASSERT_TRUE(create_string.ok());

  TypeParam source = 10;
  std::string source_str = (*create_string)(source);
  riegeli::StringReader<> source_reader(source_str);

  int64_t adjustment = 10;

  TypeParam expected = source + adjustment;
  std::string expected_str = (*create_string)(expected);

  std::string result;
  riegeli::StringWriter<> destination(&result);

  EXPECT_THAT(CopyBigEndian<TypeParam>(source_reader, destination, adjustment),
              IsOkAndHolds(expected));

  EXPECT_TRUE(destination.Close());
  EXPECT_EQ(result, expected_str);
}

TYPED_TEST_P(CopyBigEndianTests, SucceedsWithZeroAdjustment) {
  auto create_string = GetCreateStringFunction<TypeParam>();
  ASSERT_TRUE(create_string.ok());

  TypeParam source = 42;
  std::string source_str = (*create_string)(source);
  riegeli::StringReader<> source_reader(source_str);

  std::string result;
  riegeli::StringWriter<> destination(&result);

  EXPECT_THAT(
      credentio::CopyBigEndian<TypeParam>(source_reader, destination, 0),
      IsOkAndHolds(source));

  EXPECT_TRUE(destination.Close());
  EXPECT_EQ(result, source_str);
}

TEST(ReadNullTerminatedStringTests, SucceedsWithNullTerminator) {
  std::string source_str("hello\0world", 11);
  riegeli::StringReader<> reader(source_str);
  std::string output;
  EXPECT_TRUE(ReadNullTerminatedString(reader, 10, output));
  EXPECT_EQ(output, "hello");
  EXPECT_EQ(reader.pos(), 6);
}

TEST(ReadNullTerminatedStringTests, SucceedsWithNullTerminatorAtStart) {
  std::string source_str("\0helloworld", 11);
  riegeli::StringReader<> reader(source_str);
  std::string output;
  EXPECT_TRUE(ReadNullTerminatedString(reader, 6, output));
  EXPECT_EQ(output, "");
  EXPECT_EQ(reader.pos(), 1);
}

TEST(ReadNullTerminatedStringTests, SucceedsWithMultipleNulls) {
  std::string source_str("abc\0def\0ghi", 11);
  riegeli::StringReader<> reader(source_str);
  std::string output;
  EXPECT_TRUE(ReadNullTerminatedString(reader, 8, output));
  EXPECT_EQ(output, "abc");
  EXPECT_EQ(reader.pos(), 4);
}

TEST(ReadNullTerminatedStringTests, FailsWithoutNullTerminatorWithinBounds) {
  std::string source_str = "abcdefghij";
  riegeli::StringReader<> reader(source_str);
  std::string output;
  EXPECT_FALSE(ReadNullTerminatedString(reader, 5, output));
  EXPECT_EQ(output, "");
  EXPECT_EQ(reader.pos(), 0);
}

TEST(ReadNullTerminatedStringTests, FailsIfInsufficientBytesToRead) {
  std::string source_str = "abc";
  riegeli::StringReader<> reader(source_str);
  std::string output;
  EXPECT_FALSE(ReadNullTerminatedString(reader, 5, output));
}

REGISTER_TYPED_TEST_SUITE_P(CopyBigEndianTests, FailsWhenSourceClosed,
                            FailsWhenDestinationClosed, FailsWhenNoSource,
                            FailsWhenTooLarge, Succeeds,
                            SucceedsWithZeroAdjustment);

using CopyBigEndianTypes =
    ::testing::Types<uint8_t, uint16_t, uint32_t, uint64_t>;

INSTANTIATE_TYPED_TEST_SUITE_P(_, CopyBigEndianTests, CopyBigEndianTypes);

}  // namespace
}  // namespace credentio
