# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: percent
#       format_version: '1.3'
#       jupytext_version: 1.19.1
# ---

# %% [markdown]
# # Listing Available Classes
#
# Use `get_class_names()` to see what's available, or `get_all_registered_class_metadata()` for detailed information.

# %%
from pyrit.registry import ScenarioRegistry
from pyrit.setup import IN_MEMORY, initialize_pyrit_async
from pyrit.setup.initializers import LoadDefaultDatasets, TechniqueInitializer

dataset_initializer = LoadDefaultDatasets()
dataset_initializer.set_params_from_args(args={"dataset_names": ["garak_slur_terms_en", "garak_web_html_js"]})
await initialize_pyrit_async(
    memory_db_type=IN_MEMORY,
    initializers=[TechniqueInitializer(), dataset_initializer],
)  # type: ignore

registry = ScenarioRegistry.get_registry_singleton()

# Get all registered names
names = registry.get_class_names()
print(f"Available scenarios: {names[:5]}...")  # Show first 5

# Get detailed metadata
metadata = registry.get_all_registered_class_metadata()
for item in metadata[:2]:  # Show first 2
    print(f"\n{item.class_name}:")
    print(f"  Description: {item.class_description[:80]}...")

# %% [markdown]
# ## Getting a Class
#
# Use `get_class()` to retrieve a class by name. This returns the class itself, not an instance.

# %%
scenario_class = registry.get_class("garak.encoding")

print(f"Got class: {scenario_class}")
print(f"Class name: {scenario_class.__name__}")

# %% [markdown]
# ## Creating Instances
#
# Once you have a class, instantiate it with your parameters. You can also use `create_instance()` as a shortcut.

# %%
from pyrit.prompt_target import OpenAIChatTarget

target = OpenAIChatTarget()

# Option 1: Get class then instantiate
encoding_class = registry.get_class("garak.encoding")
scenario = encoding_class()  # type: ignore

# Set the objective target, then initialize
scenario.set_params_from_args(args={"objective_target": target})  # type: ignore
await scenario.initialize_async()  # type: ignore

# Option 2: Use create_instance() shortcut
# scenario = registry.create_instance("garak.encoding", objective_target=my_target, ...)

print("Scenarios can be instantiated with your target and parameters")

# %% [markdown]
# ## Checking Registration
#
# Registries support standard Python container operations.

# %%
# Check if a name is registered
print(f"'garak.encoding' registered: {'garak.encoding' in registry}")
print(f"'nonexistent' registered: {'nonexistent' in registry}")

# Get count of registered classes
print(f"Total scenarios: {len(registry)}")

# Iterate over names
for name in list(registry)[:3]:
    print(f"  - {name}")

# %% [markdown]
# ## Using different registries
#
# There can be multiple registries. Below is doing a similar thing with the `InitializerRegistry`.

# %%
from pyrit.registry import InitializerRegistry

initializer_registry = InitializerRegistry.get_registry_singleton()

# Get all registered names
initializer_names = initializer_registry.get_class_names()
print(f"Available initializers: {initializer_names[:5]}...")  # Show first 5

# Get detailed metadata
for init_item in initializer_registry.get_all_registered_class_metadata()[:2]:  # Show first 2
    print(f"\n{init_item.registry_name}:")
    print(f"  Class: {init_item.class_name}")
    print(f"  Description: {init_item.class_description[:80]}...")
