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

#include <memory>
#include <optional>
#include <string>
#include <utility>

#include "absl/log/check.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/status_matchers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "assertion/assertion_parser.h"
#include "cbor/cbor.h"
#include "cbor/parse.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "jumbf/box.h"
#include "jumbf/parse.h"
#include "proto/actions_assertion.cbor.h"
#include "proto/actions_assertion.pb.h"
#include "proto/assertion.pb.h"
#include "proto/bmff_based_hash_assertion.cbor.h"
#include "proto/bmff_based_hash_assertion.pb.h"
#include "proto/boxes_hash_assertion.cbor.h"
#include "proto/boxes_hash_assertion.pb.h"
#include "proto/data_hash_assertion.cbor.h"
#include "proto/data_hash_assertion.pb.h"
#include "proto/ingredient_assertion.cbor.h"
#include "proto/ingredient_assertion.pb.h"
#include "testing/proto_test_utils.h"
#include "testing/test_validation_tracker.h"

namespace credentio {

namespace {

using ::absl_testing::IsOk;
using ::absl_testing::StatusIs;
using ::cbor::Parse;
using ::credentio_testing::EqualsProto;
using ::credentio_testing::ParseTextProtoOrDie;
using ::testing::HasSubstr;

TEST(AssertionEncoderTest, UnsupportedAssertionToEncode) {
  auto assertion = ParseTextProtoOrDie<Assertion>(R"pb(
    label: "unsupported_assertion"
  )pb");

  StandardAssertionEncoder encoder;
  EXPECT_THAT(encoder.ToCbor(assertion),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Assertion not supported.")));
}

TEST(AssertionEncoderTest, EncodeAction) {
  auto assertion = ParseTextProtoOrDie<Assertion>(R"pb(
    label: "c2pa.actions.v2"
    actions {
      all_actions_included: true
      actions {
        action: "c2pa.created"
        digital_source_type: "http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia"
        software_agent {
          name: "Joe\'s Photo Editor"
          version: "2.0"
          operating_system: "Windows 10"
        }
        parameters {
          instance_id: "ed610ae51f604002be3dbf0c589a2f1f"
          ingredients {
            url: "self#jumbf=c2pa/joe-ed:urn:uuid:ABCD/c2pa.assertions/c2pa.ingredient__1"
            algorithm: "sha256"
            hash: "hash"
          }
          ingredients {
            url: "self#jumbf=c2pa/joe-ed:urn:uuid:EFGH/c2pa.assertions/c2pa.ingredient__2"
            algorithm: "sha256"
            hash: "hash"
          }
        }
      }
      actions {
        action: "c2pa.filtered"
        software_agent {
          name: "Joe\'s Photo Editor"
          version: "2.0"
          operating_system: "Windows 10"
        }
      }
      actions { action: "c2pa.cropped", software_agent_index: 1 }
      templates {
        action: "com.joesphoto.filter"
        description: "Magic Filter"
        digital_source_type: "http://cv.iptc.org/newscodes/digitalsourcetype/compositeSynthetic"
        software_agent { name: "Joe\'s Photo Editor" version: "2.0" }
        icon { url: "http://cdn.examplephotoagency.com/logo.svg" hash: "hash" }
      }
      software_agents {
        name: "Joe\'s Photo Editor"
        version: "2.0"
        operating_system: "Windows 10"
      }
      software_agents {
        name: "Bob\'s Photo Editor"
        version: "1.0"
        operating_system: "Windows 10"
      }
    }
  )pb");

  StandardAssertionEncoder encoder;
  auto cbor = encoder.ToCbor(assertion);
  ABSL_ASSERT_OK(cbor);
  std::string cbor_string(*cbor);
  auto parse_result = Parse(cbor_string);
  ABSL_ASSERT_OK(parse_result);
  auto map = (*parse_result)->AsMap();
  ABSL_ASSERT_OK(map);
  credentio::ActionsAssertion result;
  auto status = cbor::ToProto(*map, &result);
  ABSL_ASSERT_OK(status);
  EXPECT_THAT(result, EqualsProto(assertion.actions()));
}

TEST(AssertionEncoderTest, EncodeBmffBasedHash) {
  auto assertion = ParseTextProtoOrDie<Assertion>(R"pb(
    label: "c2pa.hash.bmff.v3"
    bmff_based_hash {
      hash: "Zm9v",
      name: "Example `c2pa.hash.bmff.v2` assertion",
      exclusions:
      [ {
        data:
        [ { value: "Zm9v", offset: 8 }],
        xpath: "/uuid"
      }
        , { xpath: "/ftyp" }
        , { xpath: "/mfra" }
        , { xpath: "/moov[1]/pssh" }
        , {
          data:
          [ { value: "Zm9v", offset: 20 }],
          xpath: "/emsg"
        }]
    }
  )pb");

  StandardAssertionEncoder encoder;
  auto cbor = encoder.ToCbor(assertion);
  ABSL_ASSERT_OK(cbor);
  std::string cbor_string(*cbor);
  auto parse_result = Parse(cbor_string);
  ABSL_ASSERT_OK(parse_result);
  auto map = (*parse_result)->AsMap();
  ABSL_ASSERT_OK(map);
  credentio::BmffBasedHashAssertion result;
  auto status = cbor::ToProto(*map, &result);
  ABSL_ASSERT_OK(status);
  EXPECT_THAT(result, EqualsProto(assertion.bmff_based_hash()));
}

TEST(AssertionEncoderTest, EncodeDataHash) {
  auto assertion = ParseTextProtoOrDie<Assertion>(R"pb(
    label: "c2pa.hash.data"
    data_hash {
      alg: "sha256",
      pad: "b64'Zm9v'",
      hash: "b64'Zm9v'",
      name: "JUMBF manifest",
      exclusions:
      [ { start: 9960, length: 4213 }
        , { start: 14173, length: 1000 }]
    }
  )pb");

  StandardAssertionEncoder encoder;
  auto cbor = encoder.ToCbor(assertion);
  ABSL_ASSERT_OK(cbor);
  std::string cbor_string(*cbor);
  auto parse_result = Parse(cbor_string);
  ABSL_ASSERT_OK(parse_result);
  auto map = (*parse_result)->AsMap();
  ABSL_ASSERT_OK(map);
  EXPECT_THAT(map->GetByteString("pad"), IsOk());
  credentio::DataHashAssertion result;
  auto status = cbor::ToProto(*map, &result);
  ABSL_ASSERT_OK(status);

  auto expected = assertion.data_hash();
  expected.clear_pad();
  auto actual = result;
  actual.clear_pad();
  EXPECT_THAT(actual, EqualsProto(expected));
}

TEST(AssertionEncoderTest, EncodeIngredientAssertion) {
  auto assertion = ParseTextProtoOrDie<Assertion>(R"pb(
    label: "c2pa.ingredient.v3"
    ingredient_v3 {
      title: "image 1.jpg",
      media_type: "image/jpeg",
      thumbnail: {
        url: "self#jumbf=c2pa/urn:c2pa:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4/c2pa.thumbnail.ingredient_1.jpg",
        hash: "b64'UjRAYWiAq4lfCRDmksWAlDJN/XtHHFFwMWymsZsm3j8='"
      },
      relationship: "parentOf",
      active_manifest: {
        url: "self#jumbf=c2pa/urn:c2pa:5E7B01FC-4932-4BAB-AB32-D4F12A8AA322",
        hash: "b64'1kjJTO108b71cL95UxgfHD3eDgk9VrCedW8n3fYTRMk='"
      },
      claim_signature: {
        url: "self#jumbf=c2pa/urn:c2pa:5E7B01FC-4932-4BAB-AB32-D4F12A8AA322/c2pa.signature",
        hash: "b64'85KAvU3+3YgtIjj6IV0fzKwj8si/85+gevVSK2Iw+S0='"
      },
      validation_results: {
        active_manifest: {
          successes:
          [ {
            code: "claimSignature.validated",
            url: "self#jumbf=c2pa/urn:c2pa:5E7B01FC-4932-4BAB-AB32-D4F12A8AA322/c2pa.signature"
          }
            , {
              code: "signingCredential.trusted",
              url: "self#jumbf=c2pa/urn:c2pa:5E7B01FC-4932-4BAB-AB32-D4F12A8AA322/c2pa.signature"
            }
            , {
              code: "timeStamp.validated",
              url: "self#jumbf=c2pa/urn:c2pa:5E7B01FC-4932-4BAB-AB32-D4F12A8AA322/c2pa.signature"
            }
            , {
              code: "timeStamp.trusted",
              url: "self#jumbf=c2pa/urn:c2pa:5E7B01FC-4932-4BAB-AB32-D4F12A8AA322/c2pa.signature"
            }
            , {
              code: "assertion.hashedURI.match",
              url: "self#jumbf=c2pa/urn:c2pa:5E7B01FC-4932-4BAB-AB32-D4F12A8AA322/c2pa.assertions/c2pa.ingredient.v3"
            }],
          informationals:
          [ {
            code: "signingCredential.ocsp.skipped",
            url: "self#jumbf=c2pa/urn:c2pa:5E7B01FC-4932-4BAB-AB32-D4F12A8AA322/c2pa.signature"
          }],
          failures: []
        },
        ingredient_deltas:
        [ {
          ingredient_assertion_uri: "self#jumbf=c2pa/urn:c2pa:5E7B01FC-4932-4BAB-AB32-D4F12A8AA322/c2pa.assertions/c2pa.ingredient.v3",
          validation_deltas: {
            successes: [],
            informationals: [],
            failures:
            [ {
              code: "assertion.hashedURI.mismatch",
              url: "self#jumbf=c2pa/urn:c2pa:F095F30E-6CD5-4BF7-8C44-CE8420CA9FB7/c2pa.assertions/c2pa.metadata"
            }]
          }
        }
          , {
            ingredient_assertion_uri: "self#jumbf=c2pa/urn:c2pa:F095F30E-6CD5-4BF7-8C44-CE8420CA9FB7/c2pa.assertions/c2pa.ingredient.v3",
            validation_deltas: {
              successes: [],
              informationals: [],
              failures:
              [ {
                code: "signingCredential.untrusted",
                url: "self#jumbf=c2pa/urn:c2pa:72C28A7C-7F5B-4301-B373-3183C10AF7C5/c2pa.signature"
              }]
            }
          }]
      }
    }
  )pb");

  StandardAssertionEncoder encoder;
  auto cbor = encoder.ToCbor(assertion);
  ABSL_ASSERT_OK(cbor);
  std::string cbor_string(*cbor);
  auto parse_result = Parse(cbor_string);
  ABSL_ASSERT_OK(parse_result);
  auto map = (*parse_result)->AsMap();
  ABSL_ASSERT_OK(map);
  credentio::IngredientAssertionV3 result;
  auto status = cbor::ToProto(*map, &result);
  ABSL_ASSERT_OK(status);
  EXPECT_THAT(result, EqualsProto(assertion.ingredient_v3()));
}

TEST(AssertionEncoderTest, EncodeBoxesHash) {
  auto assertion = ParseTextProtoOrDie<Assertion>(R"pb(
    label: "c2pa.hash.boxes"
    boxes_hash {
      alg: "sha256",
      boxes:
      [ { names: [ "SOI", "APP0", "APP2" ], hash: "b64'Zm9v'" }
        , { names: [ "C2PA" ], hash: "b64'YmFy'" }]
    }
  )pb");

  StandardAssertionEncoder encoder;
  auto cbor = encoder.ToCbor(assertion);
  ABSL_ASSERT_OK(cbor);
  std::string cbor_string(*cbor);
  auto parse_result = Parse(cbor_string);
  ABSL_ASSERT_OK(parse_result);
  auto map = (*parse_result)->AsMap();
  ABSL_ASSERT_OK(map);
  credentio::BoxesHashAssertion result;
  auto status = cbor::ToProto(*map, &result);
  ABSL_ASSERT_OK(status);
  EXPECT_THAT(result, EqualsProto(assertion.boxes_hash()));
}

TEST(GetAssertionEncoderTest, ReturnsSameInstanceForSameParam) {
  const auto& encoder1 = GetAssertionEncoder(true);
  const auto& encoder2 = GetAssertionEncoder(true);
  EXPECT_EQ(&encoder1, &encoder2);

  const auto& encoder3 = GetAssertionEncoder(false);
  const auto& encoder4 = GetAssertionEncoder(false);
  EXPECT_EQ(&encoder3, &encoder4);
}

TEST(GetAssertionEncoderTest, ReturnsDifferentInstancesForDifferentParams) {
  const auto& encoder1 = GetAssertionEncoder(true);
  const auto& encoder2 = GetAssertionEncoder(false);
  EXPECT_NE(&encoder1, &encoder2);
}

absl::StatusOr<Assertion> ParseAssertionBox(absl::string_view assertion_data) {
  ABSL_ASSIGN_OR_RETURN(auto assertion_box,
                        jumbf::ConsumeSuperBox(&assertion_data, 9));
  if (assertion_box.contents.size() != 1) {
    return absl::InvalidArgumentError(absl::StrCat(
        "the content size is not 1, but ", assertion_box.contents.size()));
  }
  AssertionParser parser;
  TestValidationTracker validation_tracker;
  std::optional<Assertion> assertion =
      parser.ParseCbor(assertion_box.description.label.value_or(""),
                       assertion_box.contents[0].Get<jumbf::CborBox>().payload,
                       validation_tracker.tracker());
  if (!assertion.has_value()) {
    return absl::InvalidArgumentError(
        absl::StrJoin(validation_tracker.GetFailures(), ";"));
  }
  return assertion.value();
}

TEST(AssertionEncoderTest, ToJumbf) {
  StandardAssertionEncoder encoder(
      /*skip_validity_checks_for_test=*/false);
  auto assertion = ParseTextProtoOrDie<Assertion>(R"pb(
    label: "c2pa.actions.v2"
    actions {
      actions {
        action: "c2pa.created"
        software_agent { name: "test generator" }
        description: "created for testing"
        digital_source_type: "https://cv.iptc.org/newscodes/digitalsourcetype/computationalCapture"
      }
    }
  )pb");
  auto assertion_box = encoder.ToJumbf(assertion);
  ABSL_ASSERT_OK(assertion_box);
  auto serialized = std::move(*assertion_box).AsCord();

  auto parsed_assertion = ParseAssertionBox(serialized.Flatten());
  ABSL_ASSERT_OK(parsed_assertion);
  EXPECT_THAT(*parsed_assertion, EqualsProto(assertion));
}

}  // namespace
}  // namespace credentio
