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

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

#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/notification.h"
#include "async/async_context.h"
#include "claim/generator.h"
#include "claim/manifest_box.h"
#include "claim/manifest_box_assembler.h"
#include "claim/signer.h"
#include "crypto/hash.h"
#include "generator/generator.h"
#include "generator/generator_options.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "proto/generator.pb.h"
#include "proto/generator_info.pb.h"
#include "salt/salt_generator.h"
#include "testing/proto_test_utils.h"

namespace credentio {
namespace {

using ::absl_testing::StatusIs;
using ::credentio_testing::ParseTextProtoOrDie;
using ::testing::HasSubstr;
using ::testing::NotNull;

class FakeClaimSigner : public ClaimSigner {
 public:
  void Sign(absl::string_view claim, Options options,
            absl::AnyInvocable<void(absl::StatusOr<SignResult>) &&> cb)
      const override {
    std::move(cb)(SignResult{.signature = "fake_sig"});
  }
};

class TrackingManifestBoxAssembler : public ManifestBoxAssembler {
 public:
  explicit TrackingManifestBoxAssembler(std::string name, int* call_count)
      : name_(std::move(name)), call_count_(call_count) {}

  absl::StatusOr<ManifestBox> Assemble(
      const GenerateManifestStoreRequest& request) const override {
    (*call_count_)++;
    return absl::InternalError(name_);
  }

 private:
  std::string name_;
  int* call_count_;
};

class CountingSaltGenerator : public SaltGenerator {
 public:
  absl::StatusOr<std::string> Generate() const override {
    ++call_count_;
    return "0123456789abcdef";
  }

  int call_count() const { return call_count_; }

 private:
  mutable int call_count_ = 0;
};

TEST(GeneratorFactoryTest, ValidateOptionsRejectsNullSigningClaimSigner) {
  FakeClaimSigner template_signer;
  GeneratorOptions options;
  options.signing_claim_signer = nullptr;
  options.template_claim_signer = &template_signer;

  EXPECT_THAT(CreateGenerator(std::move(options)),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("signing_claim_signer is required")));
}

TEST(GeneratorFactoryTest, ValidateOptionsRejectsNullTemplateClaimSigner) {
  FakeClaimSigner signing_signer;
  GeneratorOptions options;
  options.signing_claim_signer = &signing_signer;
  options.template_claim_signer = nullptr;

  EXPECT_THAT(CreateGenerator(std::move(options)),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("template_claim_signer is required")));
}

TEST(GeneratorFactoryTest, ValidateOptionsRejectsNullUuidGenerator)
__attribute__((no_sanitize("nullability"))) {
  FakeClaimSigner signing_signer;
  FakeClaimSigner template_signer;
  GeneratorOptions options;
  options.signing_claim_signer = &signing_signer;
  options.template_claim_signer = &template_signer;
  options.uuid_generator = nullptr;

  EXPECT_THAT(CreateGenerator(std::move(options)),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("uuid_generator is required")));
}

TEST(GeneratorFactoryTest, ValidateOptionsRejectsNullHashFactory)
__attribute__((no_sanitize("nullability"))) {
  FakeClaimSigner signing_signer;
  FakeClaimSigner template_signer;
  GeneratorOptions options;
  options.signing_claim_signer = &signing_signer;
  options.template_claim_signer = &template_signer;
  options.hash_factory = nullptr;

  EXPECT_THAT(CreateGenerator(std::move(options)),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("hash_factory is required")));
}

TEST(GeneratorFactoryTest, ValidateOptionsRejectsNullSaltGenerator)
__attribute__((no_sanitize("nullability"))) {
  FakeClaimSigner signing_signer;
  FakeClaimSigner template_signer;
  GeneratorOptions options;
  options.signing_claim_signer = &signing_signer;
  options.template_claim_signer = &template_signer;
  options.salt_generator = nullptr;

  EXPECT_THAT(CreateGenerator(std::move(options)),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("salt_generator is required")));
}

TEST(GeneratorFactoryTest, ValidateOptionsRejectsNullManifestAssemblerFactory) {
  FakeClaimSigner signing_signer;
  FakeClaimSigner template_signer;
  GeneratorOptions options;
  options.signing_claim_signer = &signing_signer;
  options.template_claim_signer = &template_signer;
  options.manifest_assembler_factory = nullptr;

  EXPECT_THAT(CreateGenerator(std::move(options)),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("manifest_assembler_factory is required")));
}

TEST(GeneratorFactoryTest, CreateGeneratorSuccess) {
  FakeClaimSigner signing_signer;
  FakeClaimSigner template_signer;
  GeneratorOptions options;
  options.generator_info.set_name("TestGenerator");
  options.generator_info.set_spec_version("2.2.0");
  options.signing_claim_signer = &signing_signer;
  options.template_claim_signer = &template_signer;

  auto generator_or = CreateGenerator(std::move(options));
  ABSL_ASSERT_OK(generator_or);
  EXPECT_THAT(*generator_or, NotNull());
}

TEST(GeneratorFactoryTest, DualModeGeneratorDelegation) {
  FakeClaimSigner signing_signer;
  FakeClaimSigner template_signer;
  int signing_assemble_count = 0;
  int template_assemble_count = 0;

  GeneratorOptions options;
  options.generator_info.set_name("TestGenerator");
  options.generator_info.set_spec_version("2.2.0");
  options.signing_claim_signer = &signing_signer;
  options.template_claim_signer = &template_signer;
  options.manifest_assembler_factory =
      [&](const CreateManifestAssemblerOptions& opts)
      -> absl::StatusOr<std::unique_ptr<ManifestBoxAssembler>> {
    if (dynamic_cast<const TemplatedHasherFactory*>(opts.hash_factory) !=
        nullptr) {
      return std::make_unique<TrackingManifestBoxAssembler>(
          "template_assembler", &template_assemble_count);
    }
    return std::make_unique<TrackingManifestBoxAssembler>(
        "signing_assembler", &signing_assemble_count);
  };

  auto generator_or = CreateGenerator(std::move(options));
  ABSL_ASSERT_OK(generator_or);
  auto generator = std::move(*generator_or);

  // GenerateManifestStore should delegate to the signing generator.
  GenerateManifestStoreRequest gen_request;
  absl::Notification gen_done;
  absl::Status gen_status;
  generator->GenerateManifestStore(
      gen_request, AsyncContext(),
      [&](absl::StatusOr<GenerateManifestStoreResponse> res) {
        gen_status = res.status();
        gen_done.Notify();
      });
  gen_done.WaitForNotification();
  EXPECT_THAT(gen_status, StatusIs(absl::StatusCode::kInternal,
                                   HasSubstr("signing_assembler")));
  EXPECT_EQ(signing_assemble_count, 1);
  EXPECT_EQ(template_assemble_count, 0);

  // GenerateManifestStoreTemplate should delegate to the template generator.
  absl::Notification template_done;
  absl::Status template_status;
  generator->GenerateManifestStoreTemplate(
      gen_request, AsyncContext(),
      [&](absl::StatusOr<ManifestStoreTemplate> res) {
        template_status = res.status();
        template_done.Notify();
      });
  template_done.WaitForNotification();
  EXPECT_THAT(template_status, StatusIs(absl::StatusCode::kInternal,
                                        HasSubstr("template_assembler")));
  EXPECT_EQ(signing_assemble_count, 1);
  EXPECT_EQ(template_assemble_count, 1);

  // FinalizeManifestStore should delegate to the signing generator.
  FinalizeManifestStoreRequest fin_request;
  absl::Notification fin_done;
  absl::Status fin_status;
  generator->FinalizeManifestStore(
      fin_request, AsyncContext(),
      [&](absl::StatusOr<FinalizeManifestStoreResponse> res) {
        fin_status = res.status();
        fin_done.Notify();
      });
  fin_done.WaitForNotification();
  EXPECT_THAT(fin_status, StatusIs(absl::StatusCode::kInvalidArgument,
                                   HasSubstr("generator_context")));
}

TEST(GeneratorFactoryTest, SaltGeneratorUsedBySigningAndTemplateGenerators) {
  FakeClaimSigner signing_signer;
  FakeClaimSigner template_signer;
  CountingSaltGenerator salt_generator;
  GeneratorOptions options;
  options.generator_info.set_name("TestGenerator");
  options.generator_info.set_spec_version("2.2.0");
  options.signing_claim_signer = &signing_signer;
  options.template_claim_signer = &template_signer;
  options.salt_generator = &salt_generator;
  absl::StatusOr<std::unique_ptr<ManifestStoreGenerator>> generator =
      CreateGenerator(std::move(options));
  ABSL_ASSERT_OK(generator);
  GenerateManifestStoreRequest request = ParseTextProtoOrDie(R"pb(
    hard_binding {
      box_hash {
        alg: "sha256"
        boxes { names: "some name" hash: "some hash" }
      }
    }
    actions {
      created {
        digital_source_type: "https://cv.iptc.org/newscodes/digitalsourcetype/computationalCapture"
      }
    }
  )pb");

  absl::Notification gen_done;
  (*generator)
      ->GenerateManifestStore(
          request, AsyncContext(),
          [&](absl::StatusOr<GenerateManifestStoreResponse> res) {
            gen_done.Notify();
          });
  gen_done.WaitForNotification();
  // One salt each for the hard binding and actions assertions.
  EXPECT_EQ(salt_generator.call_count(), 2);

  absl::Notification template_done;
  (*generator)
      ->GenerateManifestStoreTemplate(
          request, AsyncContext(),
          [&](absl::StatusOr<ManifestStoreTemplate> res) {
            template_done.Notify();
          });
  template_done.WaitForNotification();
  EXPECT_EQ(salt_generator.call_count(), 4);
}

}  // namespace
}  // namespace credentio
