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

#include <cstdint>
#include <string>
#include <vector>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "riegeli/bytes/string_reader.h"
#include "riegeli/bytes/string_writer.h"

namespace credentio {
namespace {

using ::absl_testing::IsOk;
using ::absl_testing::StatusIs;
using ::testing::HasSubstr;

struct SuccessfulApplicationTestCase {
  std::string name;
  std::string input;
  std::vector<ByteInstruction> instructions;
  std::string expected;
};

using SuccessfulApplicationTest =
    testing::TestWithParam<SuccessfulApplicationTestCase>;

INSTANTIATE_TEST_SUITE_P(
    ParameterizedTests, SuccessfulApplicationTest,
    testing::ValuesIn<SuccessfulApplicationTestCase>({
        {
            .name = "NoInstructions",
            .input = "hello world",
            .instructions = {},
            .expected = "hello world",
        },
        {
            .name = "EmptyInsert",
            .input = "",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kInsert,
                     .offset = 0,
                     .bytes = "foo"},
                },
            .expected = "foo",
        },
        {
            .name = "EmptyReplace",
            .input = "",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kReplace,
                     .offset = 0,
                     .bytes = "foo"},
                },
            .expected = "foo",
        },
        {
            .name = "EmptyInstruction",
            .input = "bar",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kInsert,
                     .offset = 0,
                     .bytes = ""},
                },
            .expected = "bar",
        },
        {
            .name = "InsertAtStart",
            .input = "bar",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kInsert,
                     .offset = 0,
                     .bytes = "foo"},
                },
            .expected = "foobar",
        },
        {
            .name = "InsertAtEnd",
            .input = "bar",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kInsert,
                     .offset = 3,
                     .bytes = "foo"},
                },
            .expected = "barfoo",
        },
        {
            .name = "ReplaceAtStart",
            .input = "bar",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kReplace,
                     .offset = 0,
                     .bytes = "foo"},
                },
            .expected = "foo",
        },
        {
            .name = "ReplaceAtEnd",
            .input = "bar",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kReplace,
                     .offset = 3,
                     .bytes = "foo"},
                },
            .expected = "barfoo",
        },
        {
            .name = "InsertAtMiddle",
            .input = "bar",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kInsert,
                     .offset = 1,
                     .bytes = "foo"},
                },
            .expected = "bfooar",
        },
        {
            .name = "ReplaceAtMiddle",
            .input = "bar",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kReplace,
                     .offset = 1,
                     .bytes = "foo"},
                },
            .expected = "bfoo",
        },
        {
            .name = "ReplaceInsertReplace",
            .input = "0_________0_________0_________0_________",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kReplace,
                     .offset = 10,
                     .bytes = "replace"},
                    {.operation = ByteInstruction::Operation::kInsert,
                     .offset = 17,
                     .bytes = "insert"},
                    {.operation = ByteInstruction::Operation::kReplace,
                     .offset = 30,
                     .bytes = "second"},
                },
            .expected = "0_________replaceinsert___0_________second____",
        },
        {
            .name = "InsertPastEndOfInput",
            .input = "hello world",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kInsert,
                     .offset = 30,
                     .bytes = " goodnight"},
                },
            .expected = "hello world goodnight",
        },
        {
            .name = "ReplacePastEndOfInput",
            .input = "hello world",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kReplace,
                     .offset = 30,
                     .bytes = " goodnight"},
                },
            .expected = "hello world goodnight",
        },
        {
            .name = "ReplacePastEndOfInputWithTrailingInstructions",
            .input = "hello world",
            .instructions =
                {
                    {.operation = ByteInstruction::Operation::kReplace,
                     .offset = 6,
                     .bytes = "world goodnight"},
                    {.operation = ByteInstruction::Operation::kInsert,
                     .offset = 30,
                     .bytes = " and goodbye"},
                },
            .expected = "hello world goodnight and goodbye",
        },
    }),
    [](const testing::TestParamInfo<SuccessfulApplicationTest::ParamType>&
           info) { return info.param.name; });

TEST_P(SuccessfulApplicationTest, AppliesByteInstructions) {
  riegeli::StringReader<std::string> reader(GetParam().input);
  ASSERT_THAT(reader.status(), IsOk());
  riegeli::StringWriter<std::string> writer;
  ASSERT_THAT(writer.status(), IsOk());

  EXPECT_THAT(ApplyByteInstructions(&reader, GetParam().instructions, &writer),
              IsOk());

  ASSERT_TRUE(reader.VerifyEndAndClose());
  ASSERT_TRUE(writer.Close());

  EXPECT_EQ(writer.dest(), GetParam().expected);
}

TEST_P(SuccessfulApplicationTest, AppliesByteInstructionsInPlace) {
  riegeli::StringWriter<std::string> writer(
      GetParam().input, riegeli::StringWriterBase::Options().set_append(true));
  ASSERT_THAT(writer.status(), IsOk());

  EXPECT_THAT(ApplyByteInstructions(GetParam().instructions, &writer), IsOk());

  ASSERT_TRUE(writer.Close());

  EXPECT_EQ(writer.dest(), GetParam().expected);
}

TEST(SuccessfulApplicationTest, ReaderNotAtStart) {
  riegeli::StringReader<> reader("hello world");
  ASSERT_THAT(reader.status(), IsOk());
  ASSERT_TRUE(reader.Seek(8));

  riegeli::StringWriter<std::string> writer;
  ASSERT_THAT(writer.status(), IsOk());

  EXPECT_THAT(
      ApplyByteInstructions(&reader,
                            {{.operation = ByteInstruction::Operation::kReplace,
                              .offset = 6,
                              .bytes = "W"}},
                            &writer),
      IsOk());

  ASSERT_TRUE(reader.VerifyEndAndClose());
  ASSERT_TRUE(writer.Close());

  EXPECT_EQ(writer.dest(), "hello World");
}

TEST(SuccessfulApplicationTest, WriterNotAtStart) {
  riegeli::StringWriter<std::string> writer(
      "hello world", riegeli::StringWriterBase::Options().set_append(true));
  ASSERT_THAT(writer.status(), IsOk());
  ASSERT_TRUE(writer.Seek(8));

  EXPECT_THAT(
      ApplyByteInstructions({{.operation = ByteInstruction::Operation::kReplace,
                              .offset = 6,
                              .bytes = "W"}},
                            &writer),
      IsOk());

  ASSERT_TRUE(writer.Close());

  EXPECT_EQ(writer.dest(), "hello World");
}

TEST(FailedApplicationTest, ReaderClosed) {
  riegeli::StringReader<> reader("hello world");
  ASSERT_THAT(reader.status(), IsOk());
  reader.Close();

  riegeli::StringWriter<std::string> writer;
  ASSERT_THAT(writer.status(), IsOk());

  EXPECT_THAT(ApplyByteInstructions(&reader, {}, &writer),
              StatusIs(absl::StatusCode::kFailedPrecondition,
                       HasSubstr("Object closed")));
}

TEST(FailedApplicationTest, WriterClosed) {
  riegeli::StringReader<> reader("hello world");
  ASSERT_THAT(reader.status(), IsOk());

  riegeli::StringWriter<std::string> writer;
  ASSERT_THAT(writer.status(), IsOk());
  writer.Close();

  EXPECT_THAT(ApplyByteInstructions(&reader, {}, &writer),
              StatusIs(absl::StatusCode::kFailedPrecondition,
                       HasSubstr("Object closed")));
}

TEST(FailedApplicationTest, InstructionOutOfOrder) {
  riegeli::StringReader<> reader("hello world");
  ASSERT_THAT(reader.status(), IsOk());

  riegeli::StringWriter<std::string> writer;
  ASSERT_THAT(writer.status(), IsOk());

  EXPECT_THAT(
      ApplyByteInstructions(&reader,
                            {{.operation = ByteInstruction::Operation::kReplace,
                              .offset = 5,
                              .bytes = "da"},
                             {.operation = ByteInstruction::Operation::kReplace,
                              .offset = 2,
                              .bytes = "da"}},
                            &writer),
      StatusIs(absl::StatusCode::kInvalidArgument,
               HasSubstr("must be in ascending order")));
}

class PrematureEofReader : public riegeli::StringReader<> {
 public:
  PrematureEofReader(absl::string_view data, uint64_t fake_size)
      : riegeli::StringReader<>(data), fake_size_(fake_size) {}

  std::optional<riegeli::Position> SizeImpl() override { return fake_size_; }

 private:
  uint64_t fake_size_;
};

TEST(FailedApplicationTest, UnexpectedEofDuringCopy) {
  PrematureEofReader reader("hello", 100);
  ASSERT_THAT(reader.status(), IsOk());

  riegeli::StringWriter<std::string> writer;
  ASSERT_THAT(writer.status(), IsOk());

  EXPECT_THAT(
      ApplyByteInstructions(&reader,
                            {{.operation = ByteInstruction::Operation::kReplace,
                              .offset = 10,
                              .bytes = "x"}},
                            &writer),
      StatusIs(absl::StatusCode::kDataLoss,
               HasSubstr("Unexpected EOF while copying source data")));
}

TEST(FailedApplicationTest, UnexpectedEofDuringSkip) {
  PrematureEofReader reader("hello", 100);
  ASSERT_THAT(reader.status(), IsOk());

  riegeli::StringWriter<std::string> writer;
  ASSERT_THAT(writer.status(), IsOk());

  EXPECT_THAT(
      ApplyByteInstructions(&reader,
                            {{.operation = ByteInstruction::Operation::kReplace,
                              .offset = 0,
                              .bytes = "xxxxxxxxxx"}},
                            &writer),
      StatusIs(absl::StatusCode::kDataLoss,
               HasSubstr("Unexpected EOF while skipping source data")));
}

TEST(FailedApplicationInPlaceTest, WriterClosed) {
  riegeli::StringWriter<std::string> writer(
      "hello world", riegeli::StringWriterBase::Options().set_append(true));
  ASSERT_THAT(writer.status(), IsOk());
  writer.Close();

  EXPECT_THAT(ApplyByteInstructions({}, &writer),
              StatusIs(absl::StatusCode::kDataLoss,
                       HasSubstr("failed to seek to start of file")));
}

TEST(FailedApplicationInPlaceTest, InstructionOutOfOrder) {
  riegeli::StringWriter<std::string> writer(
      "hello world", riegeli::StringWriterBase::Options().set_append(true));
  ASSERT_THAT(writer.status(), IsOk());

  EXPECT_THAT(
      ApplyByteInstructions({{.operation = ByteInstruction::Operation::kReplace,
                              .offset = 5,
                              .bytes = "da"},
                             {.operation = ByteInstruction::Operation::kReplace,
                              .offset = 2,
                              .bytes = "da"}},
                            &writer),
      StatusIs(absl::StatusCode::kInvalidArgument,
               HasSubstr("must be in ascending order")));
}

}  // namespace
}  // namespace credentio
