// 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 <utility>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "formats/format.h"
#include "riegeli/bytes/reader.h"

namespace credentio {

void FormatRegistry::Register(std::unique_ptr<Format> format) {
  for (const auto& media_type : format->mime_types()) {
    format_for_type_[media_type].push_back(format.get());
  }
  formats_.push_back(std::move(format));
}

absl::StatusOr<const Format*> FormatRegistry::GetFormat(
    absl::string_view media_type) const {
  auto it = format_for_type_.find(media_type);
  if (it == format_for_type_.end()) {
    return absl::UnimplementedError(
        absl::StrCat("Unsupported media type: ", media_type));
  }
  if (it->second.empty()) {
    return absl::UnimplementedError(
        absl::StrCat("Unsupported media type: ", media_type));
  }
  if (it->second.size() == 1) {
    return it->second[0];
  }
  return absl::UnimplementedError(
      absl::StrCat("Multiple formats support media type: ", media_type));
}

absl::StatusOr<const Format*> FormatRegistry::GetFormat(
    riegeli::Reader& asset) const {
  for (const std::unique_ptr<Format>& format : formats_) {
    absl::StatusOr<bool> is_supported = format->assessor()->IsSupported(asset);
    if (is_supported.ok() && *is_supported) {
      // Asset is supported by this format.
      return format.get();
    }
    // Errors are treated as unsupported by the format.
  }
  return absl::UnimplementedError("No applicable Format found");
}

absl::StatusOr<const Format*> FormatRegistry::GetFormat(
    absl::string_view media_type, riegeli::Reader& asset) const {
  auto it = format_for_type_.find(media_type);
  if (it == format_for_type_.end()) {
    return absl::UnimplementedError(
        absl::StrCat("Unsupported media type: ", media_type));
  }
  if (it->second.empty()) {
    return absl::UnimplementedError(
        absl::StrCat("Unsupported media type: ", media_type));
  }
  if (it->second.size() == 1) {
    return it->second[0];
  }
  for (const Format* format : it->second) {
    absl::StatusOr<bool> is_supported = format->assessor()->IsSupported(asset);
    if (is_supported.ok() && *is_supported) {
      // Asset is supported by this format.
      return format;
    }
    // Errors are treated as unsupported by the format.
  }
  return absl::UnimplementedError("No applicable Format found");
}

}  // namespace credentio
