# AUTOGENERATED - modify shared_anyscale_util in root directory to make changes
from enum import Enum, unique
import random
import string


@unique
class IDTypes(Enum):
    projects = "prj"
    snapshots = "sna"
    users = "usr"
    organizations = "org"
    organization_invitations = "orginv"
    organizations_marketing_questions = "orgmq"
    sessions = "ses"
    applied_snapshots = "asn"
    clouds = "cld"
    cloud_resources = "cldrsrc"
    cloud_resources_gcp = "cldrsrcgcp"
    permissions_projects = "ppr"
    permissions_sessions = "pse"
    permissions_snapshots = "psn"
    permissions_clouds = "pcl"
    permissions_organizations = "por"
    identities = "ide"
    autosync_sessions = "aus"
    session_state_transitions = "sst"
    server_sessions = "sss"
    session_commands = "scd"
    instances = "ins"
    instances_unique = "asi"
    application_templates = "apt"
    builds = "bld"
    session_operations = "sop"
    compute_templates = "cpt"
    usage_snapshots = "usp"
    usage_export_jobs = "uej"
    namespaces = "nsp"
    runtime_environments = "rte"
    actors = "act"
    jobs = "job"
    ray_job_submissions = "rjs"
    ha_job_notifications = "hjn"
    anonymous_jobs = "ajb"
    anonymous_actors = "aac"
    sso_configs = "sso"
    serve_deployments = "srvdep"
    ha_jobs = "prodjob"
    job_queues = "jq"
    service = "service"
    ha_job_configs = "hjc"
    ha_job_state = "hjs"
    anyscale_customer_zone = "acz"
    ha_job_goal_state = "hjgs"
    audit_log = "alg"
    cluster_statuses = "cstat"
    recent_activities = "ract"
    support_requests = "supr"
    experimental_workspaces = "expwrk"
    structured_outputs = "output"
    experimental_integrations = "expint"
    cron_job = "cronjob"
    cluster_startups = "csu"
    integrations = "int"
    service2 = "service2"
    service2_event = "service2event"
    service2_rollout = "srr"
    service2_version = "srv"
    one_time_password = "otp"  # pragma: allowlist secret
    cluster_events = "cevt"
    files = "file"
    organization_payment_info = "org_pi"
    aioa_cloud_waitlist = "aioa_cl_wlst"

    # Anyscale Endpoints tables
    endpoints_users = "euser"
    # ID for auth tokens for reference (primary key)
    endpoints_auth_tokens = "eauth"
    # Token for auth tokens to be shown to users. This token is only shown to users once.
    endpoints_auth_token_tokens = "esecret"
    # PK for auth sessions
    endpoints_sessions = "esession"
    # Token for auth sessions
    endpoints_session_token = "esessiont"
    # PK for magic links
    endpoints_magic_links = "eotp"
    # User-facing token for magic link
    endpoints_magic_link_tokens = "eotpt"
    # Metronome transaction ID
    endpoints_metronome_transactions = "mett"
    # Cluster usage ID
    cluster_usage = "cuse"
    # Fine-tuned models
    endpoints_fine_tuned_models = "efine"
    # AICAEndpoint
    endpoints_aica_endpoints = "aept"
    # AICAModel
    endpoints_aica_models = "amdl"
    # AICAModelDeployment
    endpoints_aica_model_deployments = "amdpl"
    # Fine-tune jobs
    endpoints_fine_tuning_jobs = "eftjob"
    # Fine-tune job config overrides
    endpoints_fine_tuning_job_overrides = "eftovd"
    # AICAEndpoint events
    endpoints_aica_endpoints_events = "aept_evt"
    # Endpoints vercel integrations
    endpoints_vercel_integrations = "evi"
    # Endpoints vercel integrations projects
    endpoints_vercel_integration_projects = "evp"
    # Anyscale Machine bug reports
    anyscale_machine_bug_reports = "ambr"
    # Serve deployment events
    serve_deployment_events = "srvdep_evt"
    email_magic_links = "eml"
    email_magic_link_tokens = "emlt"
    billing_versions = "billv"
    customer_aggregated_logs_configs = "calc"
    service_accounts = "sa"


_default_id_length: int = 26


def generate_token_str(length: int = _default_id_length) -> str:
    """Generates a token comprised of uppercase (letters), lowercase, and numbers (62 possible characters)."""
    return "".join(
        # `random.SystemRandom().choices()` is cryptographically secure
        # (as opposed to `random.choices()`)
        random.SystemRandom().choices(string.ascii_letters + string.digits, k=length)
    )


class IDGenerator:
    def __init__(self, type: IDTypes):  # noqa: A002
        self.type = type.value

        self.rand = random.SystemRandom()
        self.possible_characters = list(
            set(string.ascii_lowercase + string.digits)
            - {"o", "0"}  # No confusing characters
        )

    def generate_id(self, k: int = _default_id_length) -> str:
        id_part = "".join(self.rand.choices(self.possible_characters, k=k))
        return f"{self.type}_{id_part}"


# Use this to avoid global variables due to cloudpickle not having great support for them.
def generate_id(type: IDTypes, k: int = _default_id_length) -> str:  # noqa: A002
    generator = IDGenerator(type)
    return generator.generate_id(k=k)
