# DO NOT EDIT — generated by _gen/ from the OpenAPI spec.
# Regenerate with: ./client_gen.sh
from __future__ import annotations

from typing import Any

import httpx

from goodmem._base import _op_meta, _expand_label_filters
from goodmem._base import _op_meta, _prepare_create_payload
from goodmem.errors import raise_for_status
from goodmem.models.api_key_response import ApiKeyResponse
from goodmem.models.create_api_key_request import CreateApiKeyRequest
from goodmem.models.create_api_key_response import CreateApiKeyResponse
from goodmem.models.list_api_keys_response import ListApiKeysResponse
from goodmem.models.update_api_key_request import UpdateApiKeyRequest


class ApikeysAPIBase:
    """Apikeys API — auto-generated structural base.

    Auto-generated structural base. Do not edit.
    Override in goodmem/api/apikeys.py to add domain-specific logic.
    """

    _create_model = CreateApiKeyRequest
    _rest_metadata: dict = {'create': {'http_method': 'POST', 'path': '/v1/apikeys', 'input_shape': 'kwargs_body', 'summary': 'Create a new API key', 'description': 'Creates a new API key for authenticating with the API. New keys start in ACTIVE status and can be used immediately for authentication. The response includes the one-time raw API key value which will not be retrievable later - clients must save this value as it cannot be recovered. Requires CREATE_APIKEY_OWN permission (or CREATE_APIKEY_ANY for admin users). Side effects include generating cryptographically secure key material, recording creation timestamp, and tracking creator ID. Returns INVALID_ARGUMENT if expires_at is set to a time in the past.', 'response': 'CreateApiKeyResponse', 'params': [{'name': 'labels', 'type': 'dict', 'source': 'body', 'required': False, 'description': 'Key-value pairs of metadata associated with the API key. Used for organization and filtering.'}, {'name': 'expires_at', 'type': 'int', 'source': 'body', 'required': False, 'alias': 'expiresAt', 'description': 'Expiration timestamp in milliseconds since epoch. If not provided, the key does not expire.'}, {'name': 'api_key_id', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'apiKeyId', 'description': 'Optional client-provided UUID for idempotent creation. If not provided, server generates a new UUID. Returns ALREADY_EXISTS if ID is already in use.'}], 'body_model': 'CreateApiKeyRequest', 'body_expr': 'CreateApiKeyRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'list': {'http_method': 'GET', 'path': '/v1/apikeys', 'input_shape': 'no_params', 'summary': 'List API keys', 'description': 'Retrieves a list of API keys belonging to the authenticated user. The list includes metadata about each key but not the actual key values or key hashes for security reasons. Requires LIST_APIKEY_OWN permission (or LIST_APIKEY_ANY for admin users to view keys from any user). This is a read-only operation with no side effects.', 'response': 'ListApiKeysResponse'}, 'update': {'http_method': 'PUT', 'path': '/v1/apikeys/{id}', 'input_shape': 'typed_request', 'summary': 'Update an API key', 'description': "Updates an existing API key with new values for status or labels. IMPORTANT: Key ID, user ownership, key material, and audit fields cannot be modified - only status (ACTIVE/INACTIVE) and labels are mutable. Requires UPDATE_APIKEY_OWN permission for keys you own (or UPDATE_APIKEY_ANY for admin users to modify any user's keys). Side effects include updating the updated_at timestamp and recording the updater's user ID. This operation is idempotent - repeated identical requests have no additional effect.", 'response': 'ApiKeyResponse', 'query_params': ['id'], 'params': [{'name': 'id', 'type': 'str', 'source': 'path', 'required': True, 'description': 'The unique identifier of the API key to update'}, {'name': 'status', 'type': 'str', 'source': 'body', 'required': False, 'description': 'New status for the API key. Allowed values: ACTIVE, INACTIVE.', 'enum': ['ACTIVE', 'INACTIVE']}, {'name': 'replace_labels', 'type': 'dict', 'source': 'body', 'required': False, 'alias': 'replaceLabels', 'description': 'Replace all existing labels with this set. Mutually exclusive with mergeLabels.'}, {'name': 'merge_labels', 'type': 'dict', 'source': 'body', 'required': False, 'alias': 'mergeLabels', 'description': 'Merge these labels with existing ones. Mutually exclusive with replaceLabels.'}], 'body_model': 'UpdateApiKeyRequest', 'body_expr': 'UpdateApiKeyRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'delete': {'http_method': 'DELETE', 'path': '/v1/apikeys/{id}', 'input_shape': 'path_query', 'summary': 'Delete an API key', 'description': "Permanently deletes an API key. This operation cannot be undone and immediately invalidates the key for all future authentication attempts. TIP: For reversible deactivation, use PUT /v1/apikeys/{id} with status=INACTIVE instead. Requires DELETE_APIKEY_OWN permission for keys you own (or DELETE_APIKEY_ANY for admin users to delete any user's keys). Side effects include permanently removing the key record from the database and immediate authentication invalidation.", 'response': 'None', 'query_params': ['id'], 'params': [{'name': 'id', 'type': 'str', 'source': 'path', 'required': True, 'description': 'The unique identifier of the API key to delete'}]}}

    def __init__(self, http: httpx.Client, headers: dict[str, str]) -> None:
        self._http = http
        self._headers = headers

    def create(self, *, labels: dict | None=None, expires_at: int | None=None, api_key_id: str | None=None) -> CreateApiKeyResponse:
        """Create a new API key

        Creates a new API key for authenticating with the API. New keys start in ACTIVE status and can be used immediately for authentication. The response includes the one-time raw API key value which will not be retrievable later - clients must save this value as it cannot be recovered. Requires CREATE_APIKEY_OWN permission (or CREATE_APIKEY_ANY for admin users). Side effects include generating cryptographically secure key material, recording creation timestamp, and tracking creator ID. Returns INVALID_ARGUMENT if expires_at is set to a time in the past.

        Args:
            labels (dict, optional): Key-value pairs of metadata associated with the API key. Used for organization and filtering.
            expires_at (int, optional): Expiration timestamp in milliseconds since epoch. If not provided, the key does not expire.
            api_key_id (str, optional): Optional client-provided UUID for idempotent creation. If not provided, server generates a new UUID. Returns ALREADY_EXISTS if ID is already in use.

        Returns:
            CreateApiKeyResponse
        """
        op = _op_meta(self, 'create')
        _params: dict = {}
        if labels is not None:
            _params['labels'] = labels
        if expires_at is not None:
            _params['expires_at'] = expires_at
        if api_key_id is not None:
            _params['api_key_id'] = api_key_id
        json_payload, data_payload, files_payload = _prepare_create_payload(
            create_model=CreateApiKeyRequest, op=op, kwargs=_params,
        )
        resp = self._http.post(
            "/v1/apikeys",
            json=json_payload,
            data=data_payload,
            files=files_payload,
            headers=self._headers,
        )
        raise_for_status(resp)
        return CreateApiKeyResponse.model_validate(resp.json())

    def list(self) -> list[ApiKeyResponse]:
        """List API keys

        Retrieves a list of API keys belonging to the authenticated user. The list includes metadata about each key but not the actual key values or key hashes for security reasons. Requires LIST_APIKEY_OWN permission (or LIST_APIKEY_ANY for admin users to view keys from any user). This is a read-only operation with no side effects.

        Returns:
            list[ApiKeyResponse]
        """
        op = _op_meta(self, 'list')
        _params: dict = {}
        params = _params
        resp = self._http.get(
            "/v1/apikeys",
            params=params or None,
            headers=self._headers,
        )
        raise_for_status(resp)
        wrapper = ListApiKeysResponse.model_validate(resp.json())
        return getattr(wrapper, 'keys', [])

    def update(self, *, id: str, request: UpdateApiKeyRequest | dict) -> ApiKeyResponse:
        """Update an API key

        Updates an existing API key with new values for status or labels. IMPORTANT: Key ID, user ownership, key material, and audit fields cannot be modified - only status (ACTIVE/INACTIVE) and labels are mutable. Requires UPDATE_APIKEY_OWN permission for keys you own (or UPDATE_APIKEY_ANY for admin users to modify any user's keys). Side effects include updating the updated_at timestamp and recording the updater's user ID. This operation is idempotent - repeated identical requests have no additional effect.

        Args:
            id (str): The unique identifier of the apikey to update.
            request (UpdateApiKeyRequest | dict): The update payload. Accepts a UpdateApiKeyRequest instance or a plain dict with the same fields. Only specified fields will be modified.

        Returns:
            ApiKeyResponse
        """
        if isinstance(request, dict):
            request = UpdateApiKeyRequest.model_validate(request)
        resp = self._http.put(
            f"/v1/apikeys/{id}",
            json=request.model_dump(by_alias=True, exclude_unset=True),
            headers=self._headers,
        )
        raise_for_status(resp)
        return ApiKeyResponse.model_validate(resp.json())

    def delete(self, *, id: str) -> None:
        """Delete an API key

        Permanently deletes an API key. This operation cannot be undone and immediately invalidates the key for all future authentication attempts. TIP: For reversible deactivation, use PUT /v1/apikeys/{id} with status=INACTIVE instead. Requires DELETE_APIKEY_OWN permission for keys you own (or DELETE_APIKEY_ANY for admin users to delete any user's keys). Side effects include permanently removing the key record from the database and immediate authentication invalidation.

        Args:
            id (str): The unique identifier of the API key to delete
        """
        resp = self._http.delete(
            f"/v1/apikeys/{id}",
            headers=self._headers,
        )
        raise_for_status(resp)


class AsyncApikeysAPIBase:
    """Async Apikeys API — auto-generated structural base.

    Auto-generated structural base. Do not edit.
    Override in goodmem/api/apikeys.py to add domain-specific logic.
    """

    _create_model = CreateApiKeyRequest
    _rest_metadata: dict = {'create': {'http_method': 'POST', 'path': '/v1/apikeys', 'input_shape': 'kwargs_body', 'summary': 'Create a new API key', 'description': 'Creates a new API key for authenticating with the API. New keys start in ACTIVE status and can be used immediately for authentication. The response includes the one-time raw API key value which will not be retrievable later - clients must save this value as it cannot be recovered. Requires CREATE_APIKEY_OWN permission (or CREATE_APIKEY_ANY for admin users). Side effects include generating cryptographically secure key material, recording creation timestamp, and tracking creator ID. Returns INVALID_ARGUMENT if expires_at is set to a time in the past.', 'response': 'CreateApiKeyResponse', 'params': [{'name': 'labels', 'type': 'dict', 'source': 'body', 'required': False, 'description': 'Key-value pairs of metadata associated with the API key. Used for organization and filtering.'}, {'name': 'expires_at', 'type': 'int', 'source': 'body', 'required': False, 'alias': 'expiresAt', 'description': 'Expiration timestamp in milliseconds since epoch. If not provided, the key does not expire.'}, {'name': 'api_key_id', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'apiKeyId', 'description': 'Optional client-provided UUID for idempotent creation. If not provided, server generates a new UUID. Returns ALREADY_EXISTS if ID is already in use.'}], 'body_model': 'CreateApiKeyRequest', 'body_expr': 'CreateApiKeyRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'list': {'http_method': 'GET', 'path': '/v1/apikeys', 'input_shape': 'no_params', 'summary': 'List API keys', 'description': 'Retrieves a list of API keys belonging to the authenticated user. The list includes metadata about each key but not the actual key values or key hashes for security reasons. Requires LIST_APIKEY_OWN permission (or LIST_APIKEY_ANY for admin users to view keys from any user). This is a read-only operation with no side effects.', 'response': 'ListApiKeysResponse'}, 'update': {'http_method': 'PUT', 'path': '/v1/apikeys/{id}', 'input_shape': 'typed_request', 'summary': 'Update an API key', 'description': "Updates an existing API key with new values for status or labels. IMPORTANT: Key ID, user ownership, key material, and audit fields cannot be modified - only status (ACTIVE/INACTIVE) and labels are mutable. Requires UPDATE_APIKEY_OWN permission for keys you own (or UPDATE_APIKEY_ANY for admin users to modify any user's keys). Side effects include updating the updated_at timestamp and recording the updater's user ID. This operation is idempotent - repeated identical requests have no additional effect.", 'response': 'ApiKeyResponse', 'query_params': ['id'], 'params': [{'name': 'id', 'type': 'str', 'source': 'path', 'required': True, 'description': 'The unique identifier of the API key to update'}, {'name': 'status', 'type': 'str', 'source': 'body', 'required': False, 'description': 'New status for the API key. Allowed values: ACTIVE, INACTIVE.', 'enum': ['ACTIVE', 'INACTIVE']}, {'name': 'replace_labels', 'type': 'dict', 'source': 'body', 'required': False, 'alias': 'replaceLabels', 'description': 'Replace all existing labels with this set. Mutually exclusive with mergeLabels.'}, {'name': 'merge_labels', 'type': 'dict', 'source': 'body', 'required': False, 'alias': 'mergeLabels', 'description': 'Merge these labels with existing ones. Mutually exclusive with replaceLabels.'}], 'body_model': 'UpdateApiKeyRequest', 'body_expr': 'UpdateApiKeyRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'delete': {'http_method': 'DELETE', 'path': '/v1/apikeys/{id}', 'input_shape': 'path_query', 'summary': 'Delete an API key', 'description': "Permanently deletes an API key. This operation cannot be undone and immediately invalidates the key for all future authentication attempts. TIP: For reversible deactivation, use PUT /v1/apikeys/{id} with status=INACTIVE instead. Requires DELETE_APIKEY_OWN permission for keys you own (or DELETE_APIKEY_ANY for admin users to delete any user's keys). Side effects include permanently removing the key record from the database and immediate authentication invalidation.", 'response': 'None', 'query_params': ['id'], 'params': [{'name': 'id', 'type': 'str', 'source': 'path', 'required': True, 'description': 'The unique identifier of the API key to delete'}]}}

    def __init__(self, http: httpx.AsyncClient, headers: dict[str, str]) -> None:
        self._http = http
        self._headers = headers

    async def create(self, *, labels: dict | None=None, expires_at: int | None=None, api_key_id: str | None=None) -> CreateApiKeyResponse:
        """Create a new API key

        Creates a new API key for authenticating with the API. New keys start in ACTIVE status and can be used immediately for authentication. The response includes the one-time raw API key value which will not be retrievable later - clients must save this value as it cannot be recovered. Requires CREATE_APIKEY_OWN permission (or CREATE_APIKEY_ANY for admin users). Side effects include generating cryptographically secure key material, recording creation timestamp, and tracking creator ID. Returns INVALID_ARGUMENT if expires_at is set to a time in the past.

        Args:
            labels (dict, optional): Key-value pairs of metadata associated with the API key. Used for organization and filtering.
            expires_at (int, optional): Expiration timestamp in milliseconds since epoch. If not provided, the key does not expire.
            api_key_id (str, optional): Optional client-provided UUID for idempotent creation. If not provided, server generates a new UUID. Returns ALREADY_EXISTS if ID is already in use.

        Returns:
            CreateApiKeyResponse
        """
        op = _op_meta(self, 'create')
        _params: dict = {}
        if labels is not None:
            _params['labels'] = labels
        if expires_at is not None:
            _params['expires_at'] = expires_at
        if api_key_id is not None:
            _params['api_key_id'] = api_key_id
        json_payload, data_payload, files_payload = _prepare_create_payload(
            create_model=CreateApiKeyRequest, op=op, kwargs=_params,
        )
        resp = await self._http.post(
            "/v1/apikeys",
            json=json_payload,
            data=data_payload,
            files=files_payload,
            headers=self._headers,
        )
        raise_for_status(resp)
        return CreateApiKeyResponse.model_validate(resp.json())

    async def list(self) -> list[ApiKeyResponse]:
        """List API keys

        Retrieves a list of API keys belonging to the authenticated user. The list includes metadata about each key but not the actual key values or key hashes for security reasons. Requires LIST_APIKEY_OWN permission (or LIST_APIKEY_ANY for admin users to view keys from any user). This is a read-only operation with no side effects.

        Returns:
            list[ApiKeyResponse]
        """
        op = _op_meta(self, 'list')
        _params: dict = {}
        params = _params
        resp = await self._http.get(
            "/v1/apikeys",
            params=params or None,
            headers=self._headers,
        )
        raise_for_status(resp)
        wrapper = ListApiKeysResponse.model_validate(resp.json())
        return getattr(wrapper, 'keys', [])

    async def update(self, *, id: str, request: UpdateApiKeyRequest | dict) -> ApiKeyResponse:
        """Update an API key

        Updates an existing API key with new values for status or labels. IMPORTANT: Key ID, user ownership, key material, and audit fields cannot be modified - only status (ACTIVE/INACTIVE) and labels are mutable. Requires UPDATE_APIKEY_OWN permission for keys you own (or UPDATE_APIKEY_ANY for admin users to modify any user's keys). Side effects include updating the updated_at timestamp and recording the updater's user ID. This operation is idempotent - repeated identical requests have no additional effect.

        Args:
            id (str): The unique identifier of the apikey to update.
            request (UpdateApiKeyRequest | dict): The update payload. Accepts a UpdateApiKeyRequest instance or a plain dict with the same fields. Only specified fields will be modified.

        Returns:
            ApiKeyResponse
        """
        if isinstance(request, dict):
            request = UpdateApiKeyRequest.model_validate(request)
        resp = await self._http.put(
            f"/v1/apikeys/{id}",
            json=request.model_dump(by_alias=True, exclude_unset=True),
            headers=self._headers,
        )
        raise_for_status(resp)
        return ApiKeyResponse.model_validate(resp.json())

    async def delete(self, *, id: str) -> None:
        """Delete an API key

        Permanently deletes an API key. This operation cannot be undone and immediately invalidates the key for all future authentication attempts. TIP: For reversible deactivation, use PUT /v1/apikeys/{id} with status=INACTIVE instead. Requires DELETE_APIKEY_OWN permission for keys you own (or DELETE_APIKEY_ANY for admin users to delete any user's keys). Side effects include permanently removing the key record from the database and immediate authentication invalidation.

        Args:
            id (str): The unique identifier of the API key to delete
        """
        resp = await self._http.delete(
            f"/v1/apikeys/{id}",
            headers=self._headers,
        )
        raise_for_status(resp)

