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

#include <string>
#include <utility>
#include <vector>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/cord.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "claim/manifest_store_view.h"
#include "constants/labels.h"
#include "crypto/hash.h"
#include "jumbf/box.h"
#include "jumbf/box_builder.h"
#include "jumbf/encode_params.h"
#include "jumbf/utils.h"
#include "proto/hashed_uri.pb.h"

namespace credentio {

namespace {
bool IsManifestBox(const jumbf::SuperBox& super_box) {
  return super_box.description.type_uuid == kStandardManifestUuid ||
         super_box.description.type_uuid == kCompressedManifestUuid ||
         super_box.description.type_uuid == kUpdateManifestUuid ||
         super_box.description.type_uuid == kTimestampManifestUuid;
}

absl::StatusOr<HashedUri> CreateHashedUriForBox(
    absl::string_view url, absl::string_view box_raw_bytes,
    const HasherFactory& hasher_factory) {
  ABSL_ASSIGN_OR_RETURN(absl::string_view content,
                        jumbf::StripBoxHeaders(box_raw_bytes));
  ABSL_ASSIGN_OR_RETURN(auto hasher, hasher_factory.Create());
  hasher->Update(content);
  HashedUri hashed_uri;
  hashed_uri.set_url(url);
  hashed_uri.set_hash(hasher->Digest());
  return hashed_uri;
}

}  // namespace

absl::StatusOr<IngredientManifestUris>
ManifestStoreBuilder::AddIngredientManifestStore(
    absl::string_view manifest_store_bytes) {
  ABSL_ASSIGN_OR_RETURN(auto manifest_store_view,
                        ManifestStoreView::Create(manifest_store_bytes));
  ABSL_ASSIGN_OR_RETURN(auto active_manifest_view,
                        manifest_store_view.GetActiveManifest());
  std::string active_manifest_url =
      absl::StrCat(kManifestStoreUrlPrefix, active_manifest_view.label());

  IngredientManifestUris ingredient_manifest_uris;
  ABSL_ASSIGN_OR_RETURN(
      ingredient_manifest_uris.active_manifest,
      CreateHashedUriForBox(active_manifest_url,
                            active_manifest_view.superbox().raw_bytes,
                            hasher_factory_));

  ABSL_ASSIGN_OR_RETURN(auto claim_signature_view,
                        active_manifest_view.GetClaimSignature());
  ABSL_ASSIGN_OR_RETURN(
      ingredient_manifest_uris.claim_signature,
      CreateHashedUriForBox(
          absl::StrCat(active_manifest_url, kManifestLabelDelimiter,
                       kClaimSignatureLabel),
          claim_signature_view.superbox().raw_bytes, hasher_factory_));

  ingredient_manifest_stores_.push_back(manifest_store_view.superbox());
  return ingredient_manifest_uris;
}

absl::StatusOr<jumbf::BuiltSuperBox> ManifestStoreBuilder::Finalize(
    jumbf::BuiltSuperBox&& active_manifest) && {
  std::vector<absl::Cord> ingredient_manifests;
  for (const jumbf::SuperBox& manifest_store : ingredient_manifest_stores_) {
    for (const jumbf::ContentBox& box : manifest_store.contents) {
      if (!box.Holds<jumbf::SuperBox>()) {
        continue;
      }
      const jumbf::SuperBox& super_box = box.Get<jumbf::SuperBox>();
      if (!IsManifestBox(super_box)) {
        continue;
      }
      if (!super_box.description.label.has_value()) {
        continue;
      }
      ManifestInfo& manifest_info =
          manifest_info_[*super_box.description.label];
      if (manifest_info.copied_to_manifest_store) {
        continue;
      }
      ingredient_manifests.emplace_back(super_box.raw_bytes);
      manifest_info.copied_to_manifest_store = true;
    }
  }
  if (!active_manifest.description_label().has_value()) {
    return absl::InvalidArgumentError("active manifest label is missing");
  }
  if (manifest_info_[*active_manifest.description_label()]
          .copied_to_manifest_store) {
    // Shouldn't happen since manifest labels are generated randomly and
    // the active manifest can't be an ingredient of itself.
    return absl::InternalError(
        "active manifest label is also an ingredient manifest label");
  }
  jumbf::SuperBoxBuilder manifest_store_builder(
      kManifestStoreUuid,
      jumbf::DescriptionBoxOptions{.label = absl::Cord(kManifestStoreLabel)});
  // SuperBoxBuilder reverses the order of boxes added via AddChild when
  // finalized. We iterate in reverse order to preserve the order of the
  // ingredient manifests in the new manifest store.
  ABSL_RETURN_IF_ERROR(
      manifest_store_builder.AddChild(std::move(active_manifest)));
  for (int i = ingredient_manifests.size() - 1; i >= 0; --i) {
    ABSL_RETURN_IF_ERROR(
        manifest_store_builder.AddChild(std::move(ingredient_manifests[i])));
  }
  return std::move(manifest_store_builder).Finalize();
}
}  // namespace credentio
