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

#include <cstddef>
#include <memory>
#include <string>
#include <utility>

#include "absl/base/nullability.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "async/async_context.h"
#include "claim/manifest_store_view.h"
#include "cose/sig_structure.h"
#include "cose/timestamp_updater.h"

namespace credentio {

void ClaimTimestampUpdater::InsertTimestamp(
    std::string* absl_nonnull manifest_store, AsyncContext async_context,
    absl::AnyInvocable<void(absl::Status) &&> cb) const {
  auto manifest_store_view = ManifestStoreView::Create(*manifest_store);
  if (!manifest_store_view.ok()) {
    AsyncResolver<void>(async_context, std::move(cb))
        .Return(manifest_store_view.status());
    return;
  }
  auto manifest_view = manifest_store_view->GetActiveManifest();
  if (!manifest_view.ok()) {
    AsyncResolver<void>(async_context, std::move(cb))
        .Return(manifest_view.status());
    return;
  }
  auto claim_signature_view = manifest_view->GetClaimSignature();
  if (!claim_signature_view.ok()) {
    AsyncResolver<void>(async_context, std::move(cb))
        .Return(claim_signature_view.status());
    return;
  }
  auto cose_sign1 = claim_signature_view->GetStruct();
  if (!cose_sign1.ok()) {
    AsyncResolver<void>(async_context, std::move(cb))
        .Return(cose_sign1.status());
    return;
  }
  if (cose_sign1->unprotected_header.sig_tst2.has_value()) {
    AsyncResolver<void>(async_context, std::move(cb)).Return(absl::OkStatus());
    return;
  }
  auto signature = claim_signature_view->GetPayload();
  if (!signature.ok()) {
    AsyncResolver<void>(async_context, std::move(cb))
        .Return(signature.status());
    return;
  }
  auto updated_signature = std::make_shared<std::string>(*signature);
  absl::AnyInvocable<void(absl::Status) &&> done_cb =
      [manifest_store, signature = *signature, updated_signature, async_context,
       cb = std::move(cb)](absl::Status status) mutable {
        AsyncResolver<void> resolver(async_context, std::move(cb));
        if (!status.ok()) {
          resolver.Return(status);
          return;
        }
        if (updated_signature->size() != signature.size()) {
          resolver.Return(
              absl::InternalError("updated signature size does not match the "
                                  "original size."));
          return;
        }
        size_t signature_offset =
            signature.begin() - absl::string_view(*manifest_store).begin();
        manifest_store->replace(signature_offset, signature.size(),
                                *updated_signature);
        resolver.Return(absl::OkStatus());
      };

  TimestampUpdater updater(timestamp_creator_.get());
  updater.UpdateTimestamp(updated_signature.get(), async_context,
                          std::move(done_cb));
}

}  // namespace credentio
