// 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 "formats/jpeg/writer.h"

#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/die_if_null.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/notification.h"
#include "async/async_context.h"
#include "crypto/algorithms.h"
#include "formats/jpeg/app11_io.h"
#include "formats/jpeg/hasher.h"
#include "formats/jpeg/reader.h"
#include "generator/generator.h"
#include "proto/data_hash_assertion.pb.h"
#include "proto/generator.pb.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/string_writer.h"
#include "riegeli/bytes/writer.h"
#include "utils/byte_instruction.h"

namespace credentio {
namespace {

void AdjustDataHashExclusions(DataHashAssertion* absl_nonnull assertion,
                              int64_t c2pa_offset, int64_t c2pa_size) {
  for (auto& exclusion : *assertion->mutable_exclusions()) {
    if (exclusion.start() < c2pa_offset) {
      // Before the C2PA segment, so no adjustment needed.
      continue;
    }
    if (exclusion.start() == c2pa_offset) {
      // This is the C2PA segment, just need to fill in the length.
      exclusion.set_length(c2pa_size);
      continue;
    }
    // This is after the C2PA segment, so we need to add the manifest size to
    // the offset.
    exclusion.set_start(exclusion.start() + c2pa_size);
  }
}

}  // namespace

JpegWriter::JpegWriter(const ManifestStoreGenerator* absl_nonnull generator,
                       Options options)
    : generator_(*ABSL_DIE_IF_NULL(generator)), options_(std::move(options)) {}

absl::Status JpegWriter::Write(
    GenerateManifestStoreRequest request, riegeli::Reader* absl_nonnull source,
    riegeli::Writer* absl_nonnull destination,
    OutputMetadata* absl_nullable output_metadata) const {
  absl::Notification done;
  absl::Status status;
  Write(std::move(request), source, destination, output_metadata,
        AsyncContext(), [&](absl::Status s) {
          status = std::move(s);
          done.Notify();
        });
  done.WaitForNotification();
  return status;
}

void JpegWriter::Write(GenerateManifestStoreRequest request,
                       riegeli::Reader* absl_nonnull source,
                       riegeli::Writer* absl_nonnull destination,
                       OutputMetadata* absl_nullable output_metadata,
                       AsyncContext context,
                       absl::AnyInvocable<void(absl::Status) &&> cb) const {
  auto byte_instructions = std::make_shared<std::vector<ByteInstruction>>();
  WriteInternal(
      std::move(request), source, output_metadata, byte_instructions, context,
      [resolver = AsyncResolver<void>(context, std::move(cb)), source,
       destination, byte_instructions](absl::Status status) mutable {
        if (!status.ok()) {
          resolver.Return(std::move(status));
          return;
        }
        status = ApplyByteInstructions(source, *byte_instructions, destination);
        resolver.Return(std::move(status));
      });
}

absl::Status JpegWriter::Write(
    GenerateManifestStoreRequest request, riegeli::Writer* absl_nonnull asset,
    OutputMetadata* absl_nullable output_metadata) const {
  absl::Notification done;
  absl::Status status;
  Write(std::move(request), asset, output_metadata, AsyncContext(),
        [&](absl::Status s) {
          status = std::move(s);
          done.Notify();
        });
  done.WaitForNotification();
  return status;
}

void JpegWriter::Write(GenerateManifestStoreRequest request,
                       riegeli::Writer* absl_nonnull asset,
                       OutputMetadata* absl_nullable output_metadata,
                       AsyncContext context,
                       absl::AnyInvocable<void(absl::Status) &&> cb) const {
  AsyncResolver<void> resolver(context, std::move(cb));
  if (!asset->SupportsRandomAccess()) {
    resolver.Return(
        absl::InvalidArgumentError("asset does not support random access"));
    return;
  }
  if (!asset->SupportsReadMode()) {
    resolver.Return(
        absl::InvalidArgumentError("asset does not support read mode"));
    return;
  }

  riegeli::Reader* source = asset->ReadMode(0);
  if (source == nullptr) {
    resolver.Return(asset->ok()
                        ? absl::InternalError("failed to create source reader")
                        : asset->status());
    return;
  }
  if (!source->ok()) {
    resolver.Return(source->status());
    return;
  }

  auto byte_instructions = std::make_shared<std::vector<ByteInstruction>>();
  WriteInternal(std::move(request), source, output_metadata, byte_instructions,
                context,
                [resolver = std::move(resolver), asset,
                 byte_instructions](absl::Status status) mutable {
                  if (!status.ok()) {
                    resolver.Return(std::move(status));
                    return;
                  }
                  status = ApplyByteInstructions(*byte_instructions, asset);
                  resolver.Return(std::move(status));
                });
}

void JpegWriter::WriteInternal(
    GenerateManifestStoreRequest request, riegeli::Reader* absl_nonnull source,
    OutputMetadata* absl_nullable output_metadata,
    std::shared_ptr<std::vector<ByteInstruction>> byte_instructions,
    AsyncContext context, absl::AnyInvocable<void(absl::Status) &&> cb) const {
  AsyncResolver<void> resolver(context, std::move(cb));
  if (request.has_hard_binding()) {
    resolver.Return(absl::InvalidArgumentError(
        "request must not include `hard_binding` (binding is computed by "
        "JpegWriter)"));
    return;
  }

  auto exclusion_fn = [this, &request](riegeli::Reader& reader,
                                       const JpegSegment& segment) {
    return options_.exclusion_processor(reader, segment, request);
  };
  std::optional<JpegExclusionProcessor> exclusion_processor = std::nullopt;
  if (options_.exclusion_processor != nullptr) {
    exclusion_processor.emplace(std::move(exclusion_fn));
  }
  auto digest_result = DigestJpeg(*source, HashAlgorithm::kSha256,
                                  request.options().generate_multi_asset_hash(),
                                  exclusion_processor);
  if (!digest_result.ok()) {
    resolver.Return(digest_result.status());
    return;
  }

  request.mutable_hard_binding()->Swap(&digest_result->hard_binding);
  auto insertion_point = std::move(digest_result->insertion_point);

  generator_.GenerateManifestStoreTemplate(
      request, context,
      [this, request, insertion_point = std::move(insertion_point),
       output_metadata, byte_instructions, context,
       resolver = std::move(resolver)](
          absl::StatusOr<ManifestStoreTemplate> template_response) mutable {
        if (!template_response.ok()) {
          resolver.Return(template_response.status());
          return;
        }

        // Do things with Generate Template Response
        constexpr int64_t kMaxManifestStoreSizeBytes =
            100 * 1024 * 1024;  // 100 MiB
        if (template_response->manifest_store_size() <= 0 ||
            template_response->manifest_store_size() >
                kMaxManifestStoreSizeBytes) {
          resolver.Return(absl::InvalidArgumentError(
              absl::StrCat("invalid manifest store template size: ",
                           template_response->manifest_store_size())));
          return;
        }

        uint64_t embedded_size = CalculateTotalJpegApp11SegmentsSize(
            template_response->manifest_store_size());
        if (embedded_size > UINT32_MAX) {
          resolver.Return(
              absl::InternalError("estimated manifest store size is too large "
                                  "to fit in a uint32_t"));
          return;
        }

        FinalizeManifestStoreRequest finalize_request;
        finalize_request.mutable_manifest_store_template()->Swap(
            &*template_response);
        finalize_request.mutable_hard_binding()->MergeFrom(
            request.hard_binding());

        AdjustDataHashExclusions(
            finalize_request.mutable_hard_binding()->mutable_data_hash(),
            insertion_point.offset, embedded_size);

        if (finalize_request.hard_binding().part_bindings_size() > 0) {
          AdjustDataHashExclusions(finalize_request.mutable_hard_binding()
                                       ->mutable_part_bindings(0)
                                       ->mutable_data_hash(),
                                   insertion_point.offset, embedded_size);

          for (int i = 0;
               i < finalize_request.hard_binding().part_bindings_size(); ++i) {
            auto* location = finalize_request.mutable_hard_binding()
                                 ->mutable_part_bindings(i)
                                 ->mutable_location();
            if (location->byte_offset() == 0) {
              location->set_length(location->length() + embedded_size);
            } else {
              location->set_byte_offset(location->byte_offset() +
                                        embedded_size);
            }
          }
        }

        generator_.FinalizeManifestStore(
            finalize_request, context,
            [insertion_point, output_metadata, byte_instructions,
             resolver = std::move(resolver)](
                absl::StatusOr<FinalizeManifestStoreResponse>
                    finalize_response) mutable {
              if (!finalize_response.ok()) {
                resolver.Return(finalize_response.status());
                return;
              }

              std::string app11_payload;
              riegeli::StringWriter app11_writer(&app11_payload);
              auto write_status = WriteJpegApp11Payload(
                  insertion_point.segment_id,
                  finalize_response->manifest_store(), app11_writer);
              if (!write_status.ok()) {
                resolver.Return(std::move(write_status));
                return;
              }
              if (!app11_writer.Close()) {
                resolver.Return(app11_writer.status());
                return;
              }

              byte_instructions->push_back(ByteInstruction{
                  .operation = ByteInstruction::Operation::kInsert,
                  .offset = static_cast<uint64_t>(insertion_point.offset),
                  .bytes = std::move(app11_payload)});

              if (output_metadata != nullptr) {
                output_metadata->timestamp_included =
                    finalize_response->is_timestamped();
              }
              resolver.Return(absl::OkStatus());
            });
      });
}
}  // namespace credentio
