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

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

#include "absl/status/status.h"
#include "absl/status/status_macros.h"  // IWYU pragma: keep
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "formats/assessor.h"
#include "formats/asset_box.h"
#include "formats/byte_range.h"
#include "formats/extractor.h"
#include "formats/format.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/string_reader.h"

namespace credentio {
namespace {

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

class ErrorAssessor : public FormatAssessor {
 public:
  ErrorAssessor() = default;
  ~ErrorAssessor() override = default;

  absl::StatusOr<bool> IsSupported(riegeli::Reader& input) const override {
    return absl::UnimplementedError("Not implemented");
  }
};

class PassAssessor : public FormatAssessor {
 public:
  PassAssessor() = default;
  ~PassAssessor() override = default;

  absl::StatusOr<bool> IsSupported(riegeli::Reader& input) const override {
    return true;
  }
};

class FailAssessor : public FormatAssessor {
 public:
  FailAssessor() = default;
  ~FailAssessor() override = default;

  absl::StatusOr<bool> IsSupported(riegeli::Reader& input) const override {
    return false;
  }
};

class FakeExtractor : public FormatExtractor {
 public:
  FakeExtractor() = default;
  ~FakeExtractor() override = default;

  absl::StatusOr<std::string> ExtractManifestStore(
      riegeli::Reader& input) const override {
    return absl::UnimplementedError("Not implemented");
  }

  absl::StatusOr<std::optional<ByteRange>> ExtractManifestStoreLocation(
      riegeli::Reader& input, ExtractOptions options) const override {
    return absl::UnimplementedError("Not implemented");
  }

  absl::StatusOr<std::vector<AssetBox>> ExtractBoxes(
      riegeli::Reader& input, ExtractOptions options) const override {
    return absl::UnimplementedError("Not implemented");
  }

  bool MightBeC2paManifestStore(absl::string_view payload) const override {
    return true;
  }
};

class FormatRegistryTest : public ::testing::Test {
 protected:
  void SetUp() override { registry_ = std::make_unique<FormatRegistry>(); }

  void RegisterErrorFormat(std::vector<std::string> mime_types) {
    auto format = Format::Create(FormatOptions{
        .assessor = std::make_unique<ErrorAssessor>(),
        .extractor = std::make_unique<FakeExtractor>(),
        .mime_types = std::move(mime_types),
    });
    ABSL_ASSERT_OK(format);
    registry_->Register(*std::move(format));
  }

  void RegisterSuccessFormat(std::vector<std::string> mime_types) {
    auto format = Format::Create(FormatOptions{
        .assessor = std::make_unique<PassAssessor>(),
        .extractor = std::make_unique<FakeExtractor>(),
        .mime_types = std::move(mime_types),
    });
    ABSL_ASSERT_OK(format);
    registry_->Register(*std::move(format));
  }

  void RegisterFailFormat(std::vector<std::string> mime_types) {
    auto format = Format::Create(FormatOptions{
        .assessor = std::make_unique<FailAssessor>(),
        .extractor = std::make_unique<FakeExtractor>(),
        .mime_types = std::move(mime_types),
    });
    ABSL_ASSERT_OK(format);
    registry_->Register(*std::move(format));
  }

  std::unique_ptr<FormatRegistry> registry_;
};

TEST_F(FormatRegistryTest, MediaTypeNotFound) {
  EXPECT_THAT(registry_->GetFormat("jpeg"),
              StatusIs(absl::StatusCode::kUnimplemented,
                       HasSubstr("Unsupported media type: jpeg")));
}

TEST_F(FormatRegistryTest, MediaTypeWithSingleFormat) {
  RegisterSuccessFormat({"jpeg"});

  EXPECT_THAT(registry_->GetFormat("jpeg"), IsOkAndHolds(testing::NotNull()));
}

TEST_F(FormatRegistryTest, MediaTypeWithMultipleFormats) {
  RegisterSuccessFormat({"jpeg"});
  RegisterSuccessFormat({"jpeg"});

  EXPECT_THAT(registry_->GetFormat("jpeg"),
              StatusIs(absl::StatusCode::kUnimplemented,
                       HasSubstr("Multiple formats support media type: jpeg")));
}

TEST_F(FormatRegistryTest, AssetNotSupported) {
  RegisterFailFormat({"jpeg"});

  std::string asset = "asset";
  riegeli::StringReader<> input(asset);

  EXPECT_THAT(registry_->GetFormat(input),
              StatusIs(absl::StatusCode::kUnimplemented,
                       HasSubstr("No applicable Format found")));
}

TEST_F(FormatRegistryTest, AssetSupported) {
  RegisterSuccessFormat({"jpeg"});

  std::string asset = "asset";
  riegeli::StringReader<> input(asset);

  EXPECT_THAT(registry_->GetFormat(input), IsOkAndHolds(testing::NotNull()));
}

TEST_F(FormatRegistryTest, AssetFailsThenSupports) {
  RegisterFailFormat({"other"});
  RegisterSuccessFormat({"jpeg"});

  std::string asset = "asset";
  riegeli::StringReader<> input(asset);

  EXPECT_THAT(registry_->GetFormat(input), IsOkAndHolds(testing::NotNull()));
}

TEST_F(FormatRegistryTest, MediaTypeAndAssetNotSupported) {
  RegisterSuccessFormat({"other"});

  std::string asset = "asset";
  riegeli::StringReader<> input(asset);

  EXPECT_THAT(registry_->GetFormat("jpeg", input),
              StatusIs(absl::StatusCode::kUnimplemented,
                       HasSubstr("Unsupported media type: jpeg")));
}

TEST_F(FormatRegistryTest, MediaTypeAndAssetSingleFormat) {
  RegisterSuccessFormat({"other"});
  RegisterFailFormat({"jpeg"});

  std::string asset = "asset";
  riegeli::StringReader<> input(asset);

  EXPECT_THAT(registry_->GetFormat("jpeg", input),
              IsOkAndHolds(testing::NotNull()));
}

TEST_F(FormatRegistryTest, MediaTypeAndAssetMultipleFormat) {
  RegisterSuccessFormat({"other"});
  RegisterFailFormat({"jpeg"});
  RegisterSuccessFormat({"jpeg"});

  std::string asset = "asset";
  riegeli::StringReader<> input(asset);

  EXPECT_THAT(registry_->GetFormat("jpeg", input),
              IsOkAndHolds(testing::NotNull()));
}

TEST_F(FormatRegistryTest, MediaTypeAndAssetNoApplicableFormats) {
  RegisterSuccessFormat({"other"});
  RegisterFailFormat({"jpeg"});
  RegisterFailFormat({"jpeg"});

  std::string asset = "asset";
  riegeli::StringReader<> input(asset);

  EXPECT_THAT(registry_->GetFormat("jpeg", input),
              StatusIs(absl::StatusCode::kUnimplemented,
                       HasSubstr("No applicable Format found")));
}

}  // namespace
}  // namespace credentio
