// 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(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
