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

#include <sys/stat.h>

#include <cstdint>
#include <string>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/strings/str_cat.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace credentio {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::testing::Eq;
using ::testing::HasSubstr;

TEST(SigningAlgorithmTest, StringifyOk) {
  EXPECT_THAT(absl::StrCat(SigningAlgorithm::kEs256), Eq("ES256"));
  EXPECT_THAT(absl::StrCat(SigningAlgorithm::kEs384), Eq("ES384"));
  EXPECT_THAT(absl::StrCat(SigningAlgorithm::kEs512), Eq("ES512"));
  EXPECT_THAT(absl::StrCat(SigningAlgorithm::kPs256), Eq("PS256"));
  EXPECT_THAT(absl::StrCat(SigningAlgorithm::kPs384), Eq("PS384"));
  EXPECT_THAT(absl::StrCat(SigningAlgorithm::kPs512), Eq("PS512"));
  EXPECT_THAT(absl::StrCat(SigningAlgorithm::kEdDsa), Eq("EdDSA"));
}

TEST(SigningAlgorithmTest, StringifyUnrecognized) {
  std::string s;
  EXPECT_DEBUG_DEATH(
      {
        s = absl::StrCat(static_cast<SigningAlgorithm>(-999));
        EXPECT_THAT(s, Eq("UNKNOWN_SIGNING_ALGORITHM_-999"));
      },
      "unknown SigningAlgorithm enum: -999");
}

TEST(HashAlgorithmTest, StringifyOk) {
  EXPECT_THAT(absl::StrCat(HashAlgorithm::kSha256), Eq("sha256"));
  EXPECT_THAT(absl::StrCat(HashAlgorithm::kSha384), Eq("sha384"));
  EXPECT_THAT(absl::StrCat(HashAlgorithm::kSha512), Eq("sha512"));
}

TEST(HashAlgorithmTest, StringifyUnrecognized) {
  std::string s;
  EXPECT_DEBUG_DEATH(
      {
        s = absl::StrCat(static_cast<HashAlgorithm>(-999));
        EXPECT_THAT(s, Eq("UNKNOWN_HASH_ALGORITHM_-999"));
      },
      "unknown HashAlgorithm enum: -999");
}

TEST(HashSizeTest, GetSizeOk) {
  EXPECT_THAT(HashSizeBytes(HashAlgorithm::kSha256), Eq(32));
}

TEST(HashSizeTest, GetSizeUnrecognized) {
  uint64_t size;
  EXPECT_DEBUG_DEATH(
      {
        size = HashSizeBytes(static_cast<HashAlgorithm>(-999));
        EXPECT_THAT(size, Eq(0));
      },
      "unknown HashAlgorithm enum: -999");
}

TEST(NidToHashAlgorithmTest, Ok) {
  EXPECT_THAT(NidToHashAlgorithm(672),
              IsOkAndHolds(Eq(HashAlgorithm::kSha256)));
  EXPECT_THAT(NidToHashAlgorithm(673),
              IsOkAndHolds(Eq(HashAlgorithm::kSha384)));
  EXPECT_THAT(NidToHashAlgorithm(674),
              IsOkAndHolds(Eq(HashAlgorithm::kSha512)));
}

TEST(NidToHashAlgorithmTest, Invalid) {
  EXPECT_THAT(NidToHashAlgorithm(1),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("algorithm NID is not on C2PA allowlist")));
}

TEST(ParseHashAlgorithmTest, Ok) {
  EXPECT_THAT(ParseHashAlgorithm("sha256"),
              IsOkAndHolds(Eq(HashAlgorithm::kSha256)));
  EXPECT_THAT(ParseHashAlgorithm("sha384"),
              IsOkAndHolds(Eq(HashAlgorithm::kSha384)));
  EXPECT_THAT(ParseHashAlgorithm("sha512"),
              IsOkAndHolds(Eq(HashAlgorithm::kSha512)));
}

TEST(ParseHashAlgorithmTest, Invalid) {
  EXPECT_THAT(ParseHashAlgorithm("sha1"),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("unrecognized hash algorithm name")));
}

}  // namespace
}  // namespace credentio
