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

#include <memory>

#include "absl/base/nullability.h"
#include "absl/log/log.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "constants/status_codes.h"
#include "proto/ingredient_assertion.pb.h"
#include "proto/manifest.pb.h"
#include "proto/validation_result.pb.h"
#include "proto/validation_status.pb.h"
#include "validator/result.h"
#include "validator/tracker.h"

namespace credentio {

namespace {

SuccessStatusCode ConvertIngredientCodeToActiveCode(SuccessStatusCode code) {
  switch (code) {
    case SuccessStatusCode::kAssertionBmffHashMatch:
      return SuccessStatusCode::kGoogleAssertionBmffHashMatch;
    case SuccessStatusCode::kAssertionBoxesHashMatch:
      return SuccessStatusCode::kGoogleAssertionBoxesHashMatch;
    case SuccessStatusCode::kAssertionDataHashMatch:
      return SuccessStatusCode::kGoogleAssertionDataHashMatch;
    case SuccessStatusCode::kAssertionMultiAssetHashMatch:
      return SuccessStatusCode::kGoogleAssertionMultiAssetHashMatch;
    default:
      LOG(DFATAL) << "Unexpected success code: " << code;
      return code;
  }
}

FailureStatusCode ConvertIngredientCodeToActiveCode(FailureStatusCode code) {
  switch (code) {
    case FailureStatusCode::kAssertionBmffHashMismatch:
      return FailureStatusCode::kGoogleAssertionBmffHashMismatch;
    case FailureStatusCode::kAssertionBoxesHashMismatch:
      return FailureStatusCode::kGoogleAssertionBoxesHashMismatch;
    case FailureStatusCode::kAssertionDataHashMismatch:
      return FailureStatusCode::kGoogleAssertionDataHashMismatch;
    case FailureStatusCode::kAssertionBmffHashMalformed:
      return FailureStatusCode::kGoogleAssertionBmffHashMalformed;
    case FailureStatusCode::kAssertionBoxesHashUnknownBox:
      return FailureStatusCode::kGoogleAssertionBoxesHashUnknownBox;
    case FailureStatusCode::kAssertionDataHashMalformed:
      return FailureStatusCode::kGoogleAssertionDataHashMalformed;
    case FailureStatusCode::kAssertionBoxesHashMalformed:
      return FailureStatusCode::kGoogleAssertionBoxesHashMalformed;
    case FailureStatusCode::kAssertionMultiAssetHashMismatch:
      return FailureStatusCode::kGoogleAssertionMultiAssetHashMismatch;
    case FailureStatusCode::kAssertionMultiAssetHashMalformed:
      return FailureStatusCode::kGoogleAssertionMultiAssetHashMalformed;
    case FailureStatusCode::kAssertionMultiAssetHashMissingPart:
      return FailureStatusCode::kGoogleAssertionMultiAssetHashMissingPart;
    default:
      return code;
  }
}

InformationalStatusCode ConvertIngredientCodeToActiveCode(
    InformationalStatusCode code) {
  switch (code) {
    default:
      return code;
  }
}

}  // namespace

absl::StatusOr<std::unique_ptr<DualStatusTracker>>
DualStatusTracker::FromPartialValidationResult(
    PartialValidationResultProto* absl_nonnull partial_validation_result) {
  Manifest* absl_nullable assertion_manifest = GetMutableManifestForAssertion(
      partial_validation_result, partial_validation_result->hard_binding_uri());
  if (assertion_manifest == nullptr) {
    return absl::InvalidArgumentError(
        absl::StrCat("missing manifest for assertion: ",
                     partial_validation_result->hard_binding_uri()));
  }
  Manifest* active_manifest =
      partial_validation_result->mutable_active_manifest();
  return absl::WrapUnique(new DualStatusTracker(
      assertion_manifest,
      assertion_manifest == active_manifest ? nullptr : active_manifest));
}

void DualStatusTracker::RecordSuccess(
    SuccessStatusCode code, ValidationTracker::RecordOptions options) {
  assertion_tracker_->RecordSuccess(code, options);
  if (active_tracker_ != nullptr) {
    active_tracker_->RecordSuccess(ConvertIngredientCodeToActiveCode(code),
                                   options);
  }
}

void DualStatusTracker::RecordFailure(
    FailureStatusCode code, ValidationTracker::RecordOptions options) {
  assertion_tracker_->RecordFailure(code, options);
  if (active_tracker_ != nullptr) {
    active_tracker_->RecordFailure(ConvertIngredientCodeToActiveCode(code),
                                   options);
  }
}

void DualStatusTracker::RecordInformational(
    InformationalStatusCode code, ValidationTracker::RecordOptions options) {
  assertion_tracker_->RecordInformational(code, options);
  if (active_tracker_ != nullptr) {
    active_tracker_->RecordInformational(
        ConvertIngredientCodeToActiveCode(code), options);
  }
}

}  // namespace credentio
