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

#include <memory>
#include <utility>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "proto/assertion.pb.h"
#include "proto/manifest.pb.h"
#include "proto/validation_result.pb.h"
#include "testing/proto_test_utils.h"

namespace credentio {
namespace {

using ::credentio_testing::EqualsProto;
using ::credentio_testing::ParseTextProtoOrDie;
using ::testing::IsNull;
using ::testing::Pointee;

TEST(ValidationResultTest, ToProto) {
  auto proto = std::make_unique<ValidationResultProto>();
  proto->mutable_active_manifest()->set_label("test");
  ValidationResult result(std::move(proto));
  ValidationResultProto expected;
  expected.mutable_active_manifest()->set_label("test");
  EXPECT_THAT(result.proto(), EqualsProto(expected));
}

TEST(ValidationResultTest, FromRvalueProto) {
  ValidationResultProto proto;
  proto.mutable_active_manifest()->set_label("test");
  ValidationResult result(std::move(proto), "manifest_store_bytes");
  ValidationResultProto expected;
  expected.mutable_active_manifest()->set_label("test");
  EXPECT_THAT(result.proto(), EqualsProto(expected));
  EXPECT_EQ(result.manifest_store_bytes(), "manifest_store_bytes");
}

TEST(ValidationResultTest, ReleaseManifestStoreBytes) {
  ValidationResult result(ValidationResultProto(), "manifest_store_bytes");
  EXPECT_EQ(result.manifest_store_bytes(), "manifest_store_bytes");
  EXPECT_EQ(result.release_manifest_store_bytes(), "manifest_store_bytes");
}

TEST(GetAssertionTest, ReturnsAssertionFromActiveManifest) {
  PartialValidationResultProto result;
  result.mutable_active_manifest()->set_label("active_manifest");
  result.mutable_active_manifest()->add_assertions()->set_label("assertion1");
  result.mutable_active_manifest()->add_assertions()->set_label("assertion2");
  result.mutable_active_manifest()->add_assertions()->set_label("assertion3");
  EXPECT_THAT(
      GetAssertion(
          &result,
          "self#jumbf=/c2pa/active_manifest/c2pa.assertions/assertion2"),
      Pointee(
          EqualsProto(ParseTextProtoOrDie<Assertion>("label: 'assertion2'"))));
}

TEST(GetAssertionTest, ReturnsAssertionFromIngredientManifest) {
  auto result = ParseTextProtoOrDie<PartialValidationResultProto>(R"pb(
    active_manifest { label: "active_manifest" }
    ingredient_manifests {
      label: "ingredient_manifest1"
      assertions {
        label: "assertion1"
        actions {}
      }
    }
    ingredient_manifests {
      label: "ingredient_manifest2"
      assertions {
        label: "assertion1"
        data_hash {}
      }
    }
  )pb");
  EXPECT_THAT(
      GetAssertion(
          &result,
          "self#jumbf=/c2pa/ingredient_manifest2/c2pa.assertions/assertion1"),
      Pointee(EqualsProto(ParseTextProtoOrDie<Assertion>(R"pb(
        label: "assertion1"
        data_hash {}
      )pb"))));
}

TEST(GetAssertionTest, InvalidUriPrefix) {
  PartialValidationResultProto result;
  EXPECT_THAT(GetAssertion(&result, "invalid_prefix"), IsNull());
}

TEST(GetAssertionTest, InvalidUriPathLength) {
  PartialValidationResultProto result;
  EXPECT_THAT(
      GetAssertion(&result, "self#jumbf=/c2pa/active_manifest/assertion1"),
      IsNull());
}

TEST(GetAssertionTest, InvalidUriAssertionsPart) {
  auto result = ParseTextProtoOrDie<PartialValidationResultProto>(R"pb(
    active_manifest {
      label: "active_manifest"
      assertions { label: "assertion1" }
    }
  )pb");
  EXPECT_THAT(
      GetAssertion(&result,
                   "self#jumbf=/c2pa/active_manifest/invalid_part/assertion1"),
      IsNull());
}

TEST(GetAssertionTest, ManifestLabelNotFound) {
  auto result = ParseTextProtoOrDie<PartialValidationResultProto>(R"pb(
    active_manifest {
      label: "active_manifest"
      assertions { label: "assertion1" }
    }
    ingredient_manifests {
      label: "ingredient_manifest1"
      assertions {
        label: "assertion1"
        actions {}
      }
    }
  )pb");
  EXPECT_THAT(GetAssertion(
                  &result,
                  "self#jumbf=/c2pa/other_manifest/c2pa.assertions/assertion1"),
              IsNull());
}

TEST(GetAssertionTest, AssertionLabelNotFound) {
  auto result = ParseTextProtoOrDie<PartialValidationResultProto>(R"pb(
    active_manifest {
      label: "active_manifest"
      assertions { label: "assertion1" }
    }
    ingredient_manifests {
      label: "ingredient_manifest1"
      assertions {
        label: "assertion1"
        actions {}
      }
    }
  )pb");
  EXPECT_THAT(
      GetAssertion(
          &result,
          "self#jumbf=/c2pa/active_manifest/c2pa.assertions/assertion2"),
      IsNull());
}

TEST(GetMutableManifestForAssertionTest, ReturnsManifestFromActiveManifest) {
  PartialValidationResultProto result;
  result.mutable_active_manifest()->set_label("active_manifest");
  result.mutable_active_manifest()->add_assertions()->set_label("assertion1");
  result.mutable_active_manifest()->add_assertions()->set_label("assertion2");
  result.mutable_active_manifest()->add_assertions()->set_label("assertion3");
  EXPECT_THAT(
      GetMutableManifestForAssertion(
          &result,
          "self#jumbf=/c2pa/active_manifest/c2pa.assertions/assertion2"),
      Pointee(EqualsProto(ParseTextProtoOrDie<Manifest>(R"pb(
        label: "active_manifest"
        assertions { label: "assertion1" }
        assertions { label: "assertion2" }
        assertions { label: "assertion3" }
      )pb"))));
}

TEST(GetMutableManifestForAssertionTest,
     ReturnsManifestFromIngredientManifest) {
  auto result = ParseTextProtoOrDie<PartialValidationResultProto>(R"pb(
    active_manifest { label: "active_manifest" }
    ingredient_manifests {
      label: "ingredient_manifest1"
      assertions {
        label: "assertion1"
        actions {}
      }
    }
    ingredient_manifests {
      label: "ingredient_manifest2"
      assertions {
        label: "assertion1"
        data_hash {}
      }
    }
  )pb");
  EXPECT_THAT(
      GetMutableManifestForAssertion(
          &result,
          "self#jumbf=/c2pa/ingredient_manifest2/c2pa.assertions/assertion1"),
      Pointee(EqualsProto(ParseTextProtoOrDie<Manifest>(R"pb(
        label: "ingredient_manifest2"
        assertions {
          label: "assertion1"
          data_hash {}
        }
      )pb"))));
}

TEST(GetMutableManifestForAssertionTest, ManifestLabelNotFound) {
  auto result = ParseTextProtoOrDie<PartialValidationResultProto>(R"pb(
    active_manifest {
      label: "active_manifest"
      assertions { label: "assertion1" }
    }
    ingredient_manifests {
      label: "ingredient_manifest1"
      assertions {
        label: "assertion1"
        actions {}
      }
    }
  )pb");
  EXPECT_THAT(GetMutableManifestForAssertion(
                  &result,
                  "self#jumbf=/c2pa/other_manifest/c2pa.assertions/assertion1"),
              IsNull());
}

TEST(GetMutableManifestForAssertionTest, InvalidUriPrefix) {
  auto result = ParseTextProtoOrDie<PartialValidationResultProto>(R"pb(
    active_manifest {
      label: "active_manifest"
      assertions { label: "assertion1" }
    }
  )pb");
  EXPECT_THAT(GetMutableManifestForAssertion(&result, "invalid_prefix"),
              IsNull());
  EXPECT_THAT(
      GetMutableManifestForAssertion(
          &result,
          "self#jumbf=/c2pb/active_manifest/c2pa.assertions/assertion1"),
      IsNull());
}

}  // namespace
}  // namespace credentio
