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

#include <memory>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "proto/manifest.pb.h"
#include "proto/validation_result.pb.h"
#include "proto/validation_status.pb.h"
#include "testing/proto_test_utils.h"

namespace credentio {
namespace {

using ::absl_testing::StatusIs;
using ::credentio_testing::EqualsProto;
using ::credentio_testing::ParseTextProtoOrDie;
using ::testing::ElementsAre;
using ::testing::Eq;

TEST(MakeFullValidationResult_Failure, MakeFullValidationResult) {
  auto partial_result = std::make_unique<PartialValidationResultProto>();
  partial_result->mutable_active_manifest()->set_label("active");
  partial_result->add_ingredient_manifests()->set_label("ingredient1");
  partial_result->add_ingredient_manifests()->set_label("ingredient2");
  EXPECT_THAT(MakeFullValidationResult(std::move(partial_result)),
              StatusIs(absl::StatusCode::kInternal));
}

TEST(MakeFullValidationResult_Success, MakeFullValidationResult) {
  auto partial_result = std::make_unique<PartialValidationResultProto>();
  partial_result->mutable_active_manifest()->set_label("active");
  partial_result->mutable_active_manifest()
      ->mutable_validation()
      ->add_successes()
      ->set_code("com.google.assertion.dataHash.match");
  partial_result->add_ingredient_manifests()->set_label("ingredient1");
  partial_result->add_ingredient_manifests()->set_label("ingredient2");
  partial_result->set_spec_version("2.4.0");
  partial_result->set_trust_list_uri("urn:google:c2pa:trust-list:test");
  auto res = MakeFullValidationResult(std::move(partial_result));
  ASSERT_TRUE(res.ok());
  auto result = std::move(*res);
  EXPECT_THAT(result->active_manifest().label(), Eq("active"));
  EXPECT_THAT(result->ingredient_manifests(),
              ElementsAre(EqualsProto(ParseTextProtoOrDie<Manifest>(R"pb(
                            label: "ingredient1"
                          )pb")),
                          EqualsProto(ParseTextProtoOrDie<Manifest>(R"pb(
                            label: "ingredient2"
                          )pb"))));
  EXPECT_THAT(result->spec_version(), Eq("2.4.0"));
  EXPECT_THAT(result->trust_list_uri(), Eq("urn:google:c2pa:trust-list:test"));
}

}  // namespace
}  // namespace credentio
