// 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 <algorithm>
#include <cstdint>
#include <optional>
#include <string>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "riegeli/base/chain.h"
#include "riegeli/bytes/chain_reader.h"
#include "riegeli/bytes/copy_all.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/writer.h"

namespace credentio {

namespace {

constexpr uint64_t kBufferChunkSize = 1024 * 1024;  // 1 MiB

absl::Status ReadDataToBuffer(riegeli::Writer& writer, int64_t length,
                              riegeli::Chain& buffer) {
  // Flush the writer to make sure the data is available for reading.
  if (!writer.Flush()) {
    return writer.status();
  }

  // Create a reader at the current position of the writer.
  riegeli::Reader* reader = writer.ReadMode(writer.pos());
  if (reader == nullptr) {
    return writer.status();
  }

  // Read data from the reader to the buffer.
  if (!reader->ReadAndAppend(length, buffer)) {
    return reader->StatusOrAnnotate(
        absl::DataLossError("Failed to read data from buffer"));
  }

  // Close the reader.
  if (!reader->Close()) {
    return reader->StatusOrAnnotate(
        absl::DataLossError("Failed to close reader"));
  }

  return absl::OkStatus();
}

absl::Status WriteDataFromBuffer(riegeli::Chain& buffer, int64_t length,
                                 riegeli::Writer& writer) {
  // Create a reader for the buffer.
  riegeli::ChainReader cr(&buffer);

  // Read data from the buffer.
  absl::string_view data;
  if (!cr.Read(length, data)) {
    return cr.StatusOrAnnotate(
        absl::DataLossError("Failed to read data from buffer"));
  }

  // Write the data to the writer.
  if (!writer.Write(data)) {
    return writer.status();
  }

  // Close the reader.
  if (!cr.Close()) {
    return cr.StatusOrAnnotate(absl::DataLossError("Failed to close reader"));
  }

  // Remove data from the buffer, done after writing as the absl::string_view
  // data is a ref into the buffer.
  buffer.RemovePrefix(length);

  return absl::OkStatus();
}

absl::Status MoveDataThroughBuffer(riegeli::Chain& buffer, int64_t length,
                                   riegeli::Writer& writer) {
  ABSL_RETURN_IF_ERROR(ReadDataToBuffer(writer, length, buffer));
  return WriteDataFromBuffer(buffer, length, writer);
}

absl::Status MoveDataThroughBuffer(riegeli::Chain& buffer,
                                   absl::string_view data,
                                   riegeli::Writer& writer) {
  buffer.Append(data);
  return WriteDataFromBuffer(buffer, data.size(), writer);
}

absl::Status PushData(riegeli::Writer& writer, riegeli::Chain& buffer,
                      int64_t end_position) {
  if (buffer.empty()) {
    // We didn't insert anything yet, so just seek
    if (!writer.Seek(end_position)) {
      return writer.StatusOrAnnotate(
          absl::DataLossError("Failed to seek writer"));
    }
    return absl::OkStatus();
  }

  uint64_t remaining_byte_count = end_position - writer.pos();

  while (remaining_byte_count > 0) {
    uint64_t count_to_move = std::min(kBufferChunkSize, remaining_byte_count);

    ABSL_RETURN_IF_ERROR(MoveDataThroughBuffer(buffer, count_to_move, writer));

    remaining_byte_count -= count_to_move;
  }
  return absl::OkStatus();
}

}  // namespace

absl::Status ApplyByteInstructions(
    riegeli::Reader* absl_nonnull source,
    absl::Span<const ByteInstruction> instructions,
    riegeli::Writer* absl_nonnull destination) {
  if (!source->Seek(0) || !destination->Seek(0)) {
    return absl::DataLossError("failed to seek to start of file");
  }

  if (instructions.empty()) {
    // No instructions, just copy the source to the destination.
    return riegeli::CopyAll(*source, *destination);
  }

  if (!source->SupportsSize() || !source->Size().has_value()) {
    return absl::InvalidArgumentError("Source does not have a size.");
  }
  uint64_t file_size = source->Size().value_or(0);
  uint64_t instruction_index = 0;

  while (source->pos() < file_size && instruction_index < instructions.size()) {
    const ByteInstruction& ins = instructions[instruction_index];

    if (ins.offset < source->pos()) {
      return absl::InvalidArgumentError(
          "Byte instruction offsets must be in ascending order");
    }
    if (ins.offset >= file_size) {
      // Next instruction is at or past the end of the file.
      break;
    }

    // Copy enough data from the source to reach the instruction offset.
    if (source->pos() < ins.offset) {
      if (!source->Copy(ins.offset - source->pos(), *destination)) {
        ABSL_RETURN_IF_ERROR(source->status());
        ABSL_RETURN_IF_ERROR(destination->status());
        return absl::DataLossError("Unexpected EOF while copying source data");
      }
    }

    // Write the data
    if (!destination->Write(ins.bytes)) {
      return destination->status();
    }

    if (ins.operation == ByteInstruction::Operation::kReplace) {
      uint64_t bytes_to_skip =
          std::min<uint64_t>(ins.bytes.size(), file_size - source->pos());
      if (!source->Skip(bytes_to_skip)) {
        ABSL_RETURN_IF_ERROR(source->status());
        return absl::DataLossError("Unexpected EOF while skipping source data");
      }
    }

    ++instruction_index;
  }

  // Copy any remaining data from the source to the destination.
  if (source->pos() < file_size) {
    ABSL_RETURN_IF_ERROR(riegeli::CopyAll(*source, *destination));
  }

  // Write any remaining instructions.
  while (instruction_index < instructions.size()) {
    const ByteInstruction& ins = instructions[instruction_index];
    if (!destination->Write(ins.bytes)) {
      return destination->status();
    }
    ++instruction_index;
  }

  return absl::OkStatus();
}

absl::Status ApplyByteInstructions(
    absl::Span<const credentio::ByteInstruction> instructions,
    riegeli::Writer* absl_nonnull writer) {
  if (!writer->Seek(0)) {
    return absl::DataLossError("failed to seek to start of file");
  }

  if (instructions.empty()) {
    return absl::OkStatus();
  }

  if (!writer->Size().has_value()) {
    return absl::InvalidArgumentError("Writer does not have a size.");
  }

  uint64_t file_size = writer->Size().value();
  riegeli::Chain buffer;

  uint64_t instruction_index = 0;

  while (writer->pos() < file_size && instruction_index < instructions.size()) {
    const ByteInstruction& ins = instructions[instruction_index];

    if (ins.offset < writer->pos()) {
      return absl::InvalidArgumentError(
          "Byte instruction offsets must be in ascending order");
    }
    if (ins.offset >= file_size) {
      // Next instruction is at or past the end of the file.
      break;
    }

    // Process enough data to reach the instruction offset.
    ABSL_RETURN_IF_ERROR(PushData(*writer, buffer, ins.offset));

    if (ins.operation == credentio::ByteInstruction::Operation::kInsert) {
      // Insert operations do not impact the current offset, just add to the
      // buffer.
      buffer.Append(ins.bytes);
    } else if (ins.operation ==
               credentio::ByteInstruction::Operation::kReplace) {
      if (buffer.empty()) {
        // If the buffer is empty, we can write the data directly to the writer.
        if (!writer->Write(ins.bytes)) {
          return writer->status();
        }
      } else {
        // If the buffer is not empty, we need to move the data through the
        // buffer.
        ABSL_RETURN_IF_ERROR(MoveDataThroughBuffer(buffer, ins.bytes, *writer));
      }
    }

    ++instruction_index;
  }

  // Process all remaining data up to the end of the file.
  if (writer->pos() < file_size) {
    ABSL_RETURN_IF_ERROR(PushData(*writer, buffer, file_size));
  }
  if (!buffer.empty()) {
    // Write any remaining data in the buffer.
    if (!writer->Write(buffer)) {
      return writer->status();
    }
  }

  // Write any remaining instructions.
  while (instruction_index < instructions.size()) {
    if (!writer->Write(instructions[instruction_index].bytes)) {
      return writer->status();
    }
    ++instruction_index;
  }

  return absl::OkStatus();
}

uint64_t CalculateBytesWritten(
    const std::vector<ByteInstruction>& byte_instructions, uint64_t file_size,
    bool is_copy) {
  uint64_t sum_replace_before_insert = 0;
  uint64_t sum_insert = 0;
  std::optional<uint64_t> first_insert_offset =
      is_copy ? std::make_optional<uint64_t>(0) : std::nullopt;

  for (const auto& byte_instruction : byte_instructions) {
    if (byte_instruction.offset >= file_size) {
      // Instructions at or past the end of the original file do not replace
      // any existing bytes; they are simply appended to the destination.
      sum_insert += byte_instruction.bytes.size();
    } else if (byte_instruction.operation ==
               ByteInstruction::Operation::kReplace) {
      if (!first_insert_offset.has_value()) {
        sum_replace_before_insert += byte_instruction.bytes.size();
      }
    } else if (byte_instruction.operation ==
               ByteInstruction::Operation::kInsert) {
      sum_insert += byte_instruction.bytes.size();
      if (!first_insert_offset.has_value()) {
        first_insert_offset = byte_instruction.offset;
      }
    }
  }

  uint64_t bytes_shifted = 0;
  if (!first_insert_offset.has_value() || *first_insert_offset >= file_size) {
    bytes_shifted = 0;
  } else {
    bytes_shifted = file_size - *first_insert_offset;
  }

  return bytes_shifted + sum_insert + sum_replace_before_insert;
}

}  // namespace credentio
