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

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

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "formats/byte_range.h"
#include "formats/zip/extractor.h"
#include "generator/generator.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "proto/generator.pb.h"
#include "proto/manifest.pb.h"
#include "proto/validation_status.pb.h"
#include "riegeli/bytes/string_reader.h"
#include "riegeli/bytes/string_writer.h"
#include "testing/nonprod_generator.h"
#include "testing/nonprod_validator.h"
#include "testing/test_file_utils.h"
#include "validator/asset_validator.h"
#include "validator/result.h"

namespace credentio {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::testing::AllOf;
using ::testing::Field;
using ::testing::Gt;
using ::testing::HasSubstr;
using ::testing::IsEmpty;
using ::testing::Optional;

class ZipWriterTest : public testing::Test {
 protected:
  void SetUp() override {
    auto generator = CreateNonProdManifestStoreGenerator({});
    ABSL_ASSERT_OK(generator);
    generator_ = *std::move(generator);
    writer_ = std::make_unique<ZipWriter>(generator_.get());
    auto validator = CreateNonProdValidator({});
    ABSL_ASSERT_OK(validator);
    validator_ = *std::move(validator);
  }
  std::unique_ptr<ManifestStoreGenerator> generator_;
  std::unique_ptr<ZipWriter> writer_;
  std::unique_ptr<AssetValidator> validator_;
};

TEST_F(ZipWriterTest, Write) {
  GenerateManifestStoreRequest request;
  request.mutable_actions()
      ->mutable_created()
      ->mutable_action_metadata()
      ->set_description("test only");

  auto source = credentio_testing::GetFileReader(
      "credentio/formats/zip/testing/"
      "no_c2pa_032_asset.pptx");
  ABSL_ASSERT_OK(source);

  std::string result;
  riegeli::StringWriter destination(&result);
  ABSL_ASSERT_OK(destination.status());

  ABSL_ASSERT_OK(writer_->Write(request, source->get(), &destination));
  ASSERT_TRUE(destination.Close());

  riegeli::StringReader result_reader(result);
  ABSL_ASSERT_OK(result_reader.status());

  EXPECT_THAT(ZipExtractor().ExtractManifestStoreLocation(result_reader, {}),
              IsOkAndHolds(Optional(AllOf(Field(&ByteRange::offset, Gt(0)),
                                          Field(&ByteRange::length, Gt(0))))));

  ASSERT_TRUE(result_reader.Seek(0));
  auto validation_result = validator_->Validate(
      result_reader,
      "application/"
      "vnd.openxmlformats-officedocument.presentationml.presentation");
  ABSL_ASSERT_OK(validation_result);
  EXPECT_THAT(
      (*validation_result)->proto().active_manifest().validation().failures(),
      IsEmpty());
}

TEST_F(ZipWriterTest, WriteWithHardBindingFails) {
  GenerateManifestStoreRequest request;
  request.mutable_actions()
      ->mutable_created()
      ->mutable_action_metadata()
      ->set_description("test only");
  request.mutable_hard_binding();

  absl::StatusOr<std::string> pptx_file_contents =
      credentio_testing::GetContents(
          "credentio/formats/zip/testing/"
          "no_c2pa_032_asset.pptx");
  ABSL_ASSERT_OK(pptx_file_contents);
  riegeli::StringReader source(*pptx_file_contents);
  ABSL_ASSERT_OK(source.status());
  std::string result;
  riegeli::StringWriter destination(&result);
  ABSL_ASSERT_OK(destination.status());
  EXPECT_THAT(writer_->Write(request, &source, &destination),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("must not include `hard_binding`")));
}

}  // namespace
}  // namespace credentio
