"""
Snowflake Account API.

The Snowflake Account API is a REST API that you can use to access, update, and perform certain actions on Account resource in Snowflake.  # noqa: E501

The version of the OpenAPI document: 0.0.1
Contact: support@snowflake.com
Generated by: https://openapi-generator.tech

Do not edit this file manually.
"""

import json
import logging
import os
import re
import tempfile

from concurrent.futures import Future
from datetime import date, datetime
from typing import Iterable, Literal, Optional, Union, overload

from dateutil.parser import parse
from pydantic import Field, StrictBool, StrictInt, StrictStr, validate_call
from typing_extensions import Annotated

import snowflake.core._http_requests

from snowflake.core._generated import rest
from snowflake.core._generated.api_client import ApiClient
from snowflake.core._internal.utils import is_running_inside_stored_procedure
from snowflake.core.account._generated import models
from snowflake.core.account._generated.models.account import Account
from snowflake.core.account._generated.models.success_response import SuccessResponse
from snowflake.core.exceptions import (  # noqa: F401
    _APITypeError,
    _APIValueError,
)


logger = logging.getLogger(__name__)


class AccountApi:
    """NOTE: This class is auto generated by OpenAPI Generator.

    Ref: https://openapi-generator.tech

    Do not edit the class manually.
    """

    def __init__(self, root, resource_class, sproc_client):
        self._root = root
        self._resource_name = "account"
        self._resource_class = resource_class

        if is_running_inside_stored_procedure():
            self._api_client = sproc_client
        else:
            self._api_client = ApiClient.get_default()

    @property
    def api_client(self):
        return self._api_client

    def deserialize(self, response, response_type):
        """Deserializes response into an object.

        :param response: RESTResponse object to be deserialized.
        :param response_type: class literal for
            deserialized object, or string of class name.

        :return: deserialized object.
        """
        # handle file downloading
        # save response body into a tmp file and return the instance
        if response_type == "file":
            return self.__deserialize_file(response)

        # fetch data from response object
        try:
            data = json.loads(response.data)
        except ValueError:
            data = response.data

        return self.__deserialize(data, response_type)

    def __deserialize(self, data, klass):
        """Deserializes dict, list, str into an object.

        :param data: dict, list or str.
        :param klass: class literal, or string of class name.

        :return: object.
        """
        if data is None:
            return None

        if isinstance(klass, str):
            if klass.startswith("Iterable["):
                sub_kls = re.match(r"Iterable\[(.*)]", klass).group(1)
                return [self.__deserialize(sub_data, sub_kls) for sub_data in data]

            if klass.startswith("Dict["):
                sub_kls = re.match(r"Dict\[([^,]*), (.*)]", klass).group(2)
                return {k: self.__deserialize(v, sub_kls) for k, v in data.items()}

            # convert str to class
            if klass in snowflake.core._http_requests.NATIVE_TYPES_MAPPING:
                klass = snowflake.core._http_requests.NATIVE_TYPES_MAPPING[klass]
            else:
                klass = getattr(models, klass)

        if klass in snowflake.core._http_requests.PRIMITIVE_TYPES:
            return self.__deserialize_primitive(data, klass)
        elif klass == object:  # noqa: E721
            return self.__deserialize_object(data)
        elif klass == date:
            return self.__deserialize_date(data)
        elif klass == datetime:
            return self.__deserialize_datetime(data)
        else:
            return self.__deserialize_model(data, klass)

    def __deserialize_file(self, response):
        """Deserializes body to file.

        Saves response body into a file in a temporary folder,
        using the filename from the `Content-Disposition` header if provided.

        :param response:  RESTResponse.
        :return: file path.
        """
        fd, path = tempfile.mkstemp(dir=self.api_client.configuration.temp_folder_path)
        os.close(fd)
        os.remove(path)

        content_disposition = response.getheader("Content-Disposition")
        if content_disposition:
            filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition).group(1)
            path = os.path.join(os.path.dirname(path), filename)

        with open(path, "wb") as f:
            f.write(response.data)

        return path

    def __deserialize_primitive(self, data, klass):
        """Deserializes string to primitive type.

        :param data: str.
        :param klass: class literal.

        :return: int, long, float, str, bool.
        """
        try:
            return klass(data)
        except UnicodeEncodeError:
            return str(data)
        except TypeError:
            return data

    def __deserialize_object(self, value):
        """Return an original value.

        :return: object.
        """
        return value

    def __deserialize_date(self, string):
        """Deserializes string to date.

        :param string: str.
        :return: date.
        """
        try:
            return parse(string).date()
        except ImportError:
            return string
        except ValueError:
            raise rest.APIError(status=0, reason=f"Failed to parse `{string}` as date object")

    def __deserialize_datetime(self, string):
        """Deserializes string to datetime.

        The string should be in iso8601 datetime format.

        :param string: str.
        :return: datetime.
        """
        try:
            return parse(string)
        except ImportError:
            return string
        except ValueError:
            raise rest.APIError(status=0, reason=(f"Failed to parse `{string}` as datetime object"))

    def __deserialize_model(self, data, klass):
        """Deserializes list or dict to model.

        :param data: dict, list.
        :param klass: class literal.
        :return: model object.
        """
        return klass.from_dict(data)

    @overload
    def create_account(self, account: Account, async_req: Literal[False] = False, **kwargs) -> SuccessResponse: ...

    @overload
    def create_account(
        self, account: Account, async_req: Literal[True] = True, **kwargs
    ) -> Future[SuccessResponse]: ...

    @overload
    def create_account(
        self, account: Account, async_req: bool = False, **kwargs
    ) -> Union[SuccessResponse, Future[SuccessResponse]]: ...

    @validate_call
    def create_account(self, account: Account, **kwargs) -> Union[SuccessResponse, Future[SuccessResponse]]:
        r"""Create an account.  # noqa: E501

        Creates a account. You must provide the full account definition when creating a account.  # noqa: E501

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> future = api.create_account(account, async_req=True)
        >>> result = future.result()
        :param account: (required)
        :type account: Account
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the urllib3.HTTPResponse object will
                                 be returned without reading/decoding response
                                 data. Default is True.
        :type _preload_content: bool, optional
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns a Future object representing the execution of the method.
        :rtype: Union[SuccessResponse, Future[SuccessResponse]]
        """
        kwargs["_return_http_data_only"] = True
        return self.create_account_with_http_info(account, **kwargs)

    @validate_call
    def create_account_with_http_info(self, account: Account, **kwargs):
        r"""Create an account.  # noqa: E501

        Creates a account. You must provide the full account definition when creating a account.  # noqa: E501

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> future = api.create_account_with_http_info(account, async_req=True)
        >>> result = future.result()
        :param account: (required)
        :type account: Account
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _return_http_data_only: response data without head status code
                                       and headers
        :type _return_http_data_only: bool, optional
        :param _preload_content: if False, the urllib3.HTTPResponse object will
                                 be returned without reading/decoding response
                                 data. Default is True.
        :type _preload_content: bool, optional
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns a Future object representing the execution of the method.
        :rtype: tuple(Union[SuccessResponse, Future[SuccessResponse]], status_code(int), headers(HTTPHeaderDict))
        """
        _params = locals()

        _all_params = ["account"]
        _all_params.extend(
            [
                "async_req",
                "_return_http_data_only",
                "_preload_content",
                "_request_timeout",
                "_request_auth",
                "_content_type",
                "_headers",
            ]
        )

        # validate the arguments
        for _key, _val in _params["kwargs"].items():
            if _key not in _all_params:
                raise _APITypeError(f"Got an unexpected keyword argument '{_key}' to method create_account")
            _params[_key] = _val
        del _params["kwargs"]

        _collection_formats = {}

        # process the path parameters
        _path_params = {}

        # process the query parameters
        _query_params = []

        # process the header parameters
        _header_params = dict(_params.get("_headers", {}))

        # process the form parameters
        _form_params = []
        _files = {}

        # process the body parameter
        _body_params = None

        if _params["account"] is not None:
            _body_params = _params["account"]

        # set the HTTP header `Accept`
        _header_params["Accept"] = self.api_client.select_header_accept(["application/json"])

        # set the HTTP header `Content-Type`
        _content_types_list = _params.get(
            "_content_type", self.api_client.select_header_content_type(["application/json"])
        )
        if _content_types_list:
            _header_params["Content-Type"] = _content_types_list

        # authentication setting
        _auth_settings = ["ExternalOAuth", "KeyPair", "ProgrammaticAccessToken", "SnowflakeOAuth"]

        _response_types_map = {
            "200": "SuccessResponse",
            "202": "SuccessAcceptedResponse",
            "400": "ErrorResponse",
            "401": "ErrorResponse",
            "403": "ErrorResponse",
            "404": "ErrorResponse",
            "405": "ErrorResponse",
            "408": "ErrorResponse",
            "409": "ErrorResponse",
            "410": "ErrorResponse",
            "429": "ErrorResponse",
            "500": "ErrorResponse",
            "503": "ErrorResponse",
            "504": "ErrorResponse",
        }

        return self.api_client.call_api(
            self._root,
            "/api/v2/accounts",
            "POST",
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get("async_req"),
            _return_http_data_only=_params.get("_return_http_data_only"),
            _preload_content=_params.get("_preload_content", True),
            _request_timeout=_params.get("_request_timeout"),
            collection_formats=_collection_formats,
            _request_auth=_params.get("_request_auth"),
            _deserialize_response_fn=self.deserialize,
        )

    @overload
    def list_accounts(
        self,
        like: Annotated[
            Optional[StrictStr],
            Field(
                description="Parameter to filter the command output by resource name. Uses case-insensitive pattern matching, with support for SQL wildcard characters."
            ),
        ] = None,
        show_limit: Annotated[
            Optional[Annotated[int, Field(le=10000, strict=True, ge=1)]],
            Field(description="Parameter to limit the maximum number of rows returned by a command."),
        ] = None,
        history: Annotated[
            Optional[StrictBool],
            Field(description="Optionally includes dropped accounts that have not yet been purged."),
        ] = None,
        async_req: Literal[False] = False,
        **kwargs,
    ) -> Iterable[Account]: ...

    @overload
    def list_accounts(
        self,
        like: Annotated[
            Optional[StrictStr],
            Field(
                description="Parameter to filter the command output by resource name. Uses case-insensitive pattern matching, with support for SQL wildcard characters."
            ),
        ] = None,
        show_limit: Annotated[
            Optional[Annotated[int, Field(le=10000, strict=True, ge=1)]],
            Field(description="Parameter to limit the maximum number of rows returned by a command."),
        ] = None,
        history: Annotated[
            Optional[StrictBool],
            Field(description="Optionally includes dropped accounts that have not yet been purged."),
        ] = None,
        async_req: Literal[True] = True,
        **kwargs,
    ) -> Future[Iterable[Account]]: ...

    @overload
    def list_accounts(
        self,
        like: Annotated[
            Optional[StrictStr],
            Field(
                description="Parameter to filter the command output by resource name. Uses case-insensitive pattern matching, with support for SQL wildcard characters."
            ),
        ] = None,
        show_limit: Annotated[
            Optional[Annotated[int, Field(le=10000, strict=True, ge=1)]],
            Field(description="Parameter to limit the maximum number of rows returned by a command."),
        ] = None,
        history: Annotated[
            Optional[StrictBool],
            Field(description="Optionally includes dropped accounts that have not yet been purged."),
        ] = None,
        async_req: bool = False,
        **kwargs,
    ) -> Union[Iterable[Account], Future[Iterable[Account]]]: ...

    @validate_call
    def list_accounts(
        self,
        like: Annotated[
            Optional[StrictStr],
            Field(
                description="Parameter to filter the command output by resource name. Uses case-insensitive pattern matching, with support for SQL wildcard characters."
            ),
        ] = None,
        show_limit: Annotated[
            Optional[Annotated[int, Field(le=10000, strict=True, ge=1)]],
            Field(description="Parameter to limit the maximum number of rows returned by a command."),
        ] = None,
        history: Annotated[
            Optional[StrictBool],
            Field(description="Optionally includes dropped accounts that have not yet been purged."),
        ] = None,
        **kwargs,
    ) -> Union[Iterable[Account], Future[Iterable[Account]]]:
        r"""List accounts.  # noqa: E501

        Lists the accessible accounts.  # noqa: E501

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> future = api.list_accounts(like, show_limit, history, async_req=True)
        >>> result = future.result()
        :param like: Parameter to filter the command output by resource name. Uses case-insensitive pattern matching, with support for SQL wildcard characters.
        :type like: str
        :param show_limit: Parameter to limit the maximum number of rows returned by a command.
        :type show_limit: int
        :param history: Optionally includes dropped accounts that have not yet been purged.
        :type history: bool
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the urllib3.HTTPResponse object will
                                 be returned without reading/decoding response
                                 data. Default is True.
        :type _preload_content: bool, optional
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns a Future object representing the execution of the method.
        :rtype: Union[Iterable[Account], Future[Iterable[Account]]]
        """
        kwargs["_return_http_data_only"] = True
        return self.list_accounts_with_http_info(like, show_limit, history, **kwargs)

    @validate_call
    def list_accounts_with_http_info(
        self,
        like: Annotated[
            Optional[StrictStr],
            Field(
                description="Parameter to filter the command output by resource name. Uses case-insensitive pattern matching, with support for SQL wildcard characters."
            ),
        ] = None,
        show_limit: Annotated[
            Optional[Annotated[int, Field(le=10000, strict=True, ge=1)]],
            Field(description="Parameter to limit the maximum number of rows returned by a command."),
        ] = None,
        history: Annotated[
            Optional[StrictBool],
            Field(description="Optionally includes dropped accounts that have not yet been purged."),
        ] = None,
        **kwargs,
    ):
        r"""List accounts.  # noqa: E501

        Lists the accessible accounts.  # noqa: E501

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> future = api.list_accounts_with_http_info(like, show_limit, history, async_req=True)
        >>> result = future.result()
        :param like: Parameter to filter the command output by resource name. Uses case-insensitive pattern matching, with support for SQL wildcard characters.
        :type like: str
        :param show_limit: Parameter to limit the maximum number of rows returned by a command.
        :type show_limit: int
        :param history: Optionally includes dropped accounts that have not yet been purged.
        :type history: bool
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _return_http_data_only: response data without head status code
                                       and headers
        :type _return_http_data_only: bool, optional
        :param _preload_content: if False, the urllib3.HTTPResponse object will
                                 be returned without reading/decoding response
                                 data. Default is True.
        :type _preload_content: bool, optional
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns a Future object representing the execution of the method.
        :rtype: tuple(Union[Iterable[Account], Future[Iterable[Account]]], status_code(int), headers(HTTPHeaderDict))
        """
        _params = locals()

        _all_params = ["like", "show_limit", "history"]
        _all_params.extend(
            [
                "async_req",
                "_return_http_data_only",
                "_preload_content",
                "_request_timeout",
                "_request_auth",
                "_content_type",
                "_headers",
            ]
        )

        # validate the arguments
        for _key, _val in _params["kwargs"].items():
            if _key not in _all_params:
                raise _APITypeError(f"Got an unexpected keyword argument '{_key}' to method list_accounts")
            _params[_key] = _val
        del _params["kwargs"]

        _collection_formats = {}

        # process the path parameters
        _path_params = {}

        # process the query parameters
        _query_params = []

        if _params.get("like") is not None:
            _query_params.append(("like", _params["like"]))

        if _params.get("show_limit") is not None:
            _query_params.append(("showLimit", _params["show_limit"]))

        if _params.get("history") is not None:
            _query_params.append(("history", _params["history"]))

        # process the header parameters
        _header_params = dict(_params.get("_headers", {}))

        # process the form parameters
        _form_params = []
        _files = {}

        # process the body parameter
        _body_params = None

        # set the HTTP header `Accept`
        _header_params["Accept"] = self.api_client.select_header_accept(["application/json"])

        # authentication setting
        _auth_settings = ["ExternalOAuth", "KeyPair", "ProgrammaticAccessToken", "SnowflakeOAuth"]

        _response_types_map = {
            "200": "Iterable[Account]",
            "202": "SuccessAcceptedResponse",
            "400": "ErrorResponse",
            "401": "ErrorResponse",
            "403": "ErrorResponse",
            "404": "ErrorResponse",
            "405": "ErrorResponse",
            "408": "ErrorResponse",
            "409": "ErrorResponse",
            "410": "ErrorResponse",
            "429": "ErrorResponse",
            "500": "ErrorResponse",
            "503": "ErrorResponse",
            "504": "ErrorResponse",
        }

        return self.api_client.call_api(
            self._root,
            "/api/v2/accounts",
            "GET",
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get("async_req"),
            _return_http_data_only=_params.get("_return_http_data_only"),
            _preload_content=_params.get("_preload_content", True),
            _request_timeout=_params.get("_request_timeout"),
            collection_formats=_collection_formats,
            _request_auth=_params.get("_request_auth"),
            _deserialize_response_fn=self.deserialize,
        )

    @overload
    def undrop_account(
        self,
        name: Annotated[str, Field(strict=True, description="Identifier (i.e. name) for the resource.")],
        async_req: Literal[False] = False,
        **kwargs,
    ) -> SuccessResponse: ...

    @overload
    def undrop_account(
        self,
        name: Annotated[str, Field(strict=True, description="Identifier (i.e. name) for the resource.")],
        async_req: Literal[True] = True,
        **kwargs,
    ) -> Future[SuccessResponse]: ...

    @overload
    def undrop_account(
        self,
        name: Annotated[str, Field(strict=True, description="Identifier (i.e. name) for the resource.")],
        async_req: bool = False,
        **kwargs,
    ) -> Union[SuccessResponse, Future[SuccessResponse]]: ...

    @validate_call
    def undrop_account(
        self, name: Annotated[str, Field(strict=True, description="Identifier (i.e. name) for the resource.")], **kwargs
    ) -> Union[SuccessResponse, Future[SuccessResponse]]:
        r"""Restore an account.  # noqa: E501

        Restores a dropped account that has not yet been permanently deleted (a dropped account that is within its grace period).  # noqa: E501

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> future = api.undrop_account(name, async_req=True)
        >>> result = future.result()
        :param name: Identifier (i.e. name) for the resource. (required)
        :type name: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the urllib3.HTTPResponse object will
                                 be returned without reading/decoding response
                                 data. Default is True.
        :type _preload_content: bool, optional
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns a Future object representing the execution of the method.
        :rtype: Union[SuccessResponse, Future[SuccessResponse]]
        """
        kwargs["_return_http_data_only"] = True
        return self.undrop_account_with_http_info(name, **kwargs)

    @validate_call
    def undrop_account_with_http_info(
        self, name: Annotated[str, Field(strict=True, description="Identifier (i.e. name) for the resource.")], **kwargs
    ):
        r"""Restore an account.  # noqa: E501

        Restores a dropped account that has not yet been permanently deleted (a dropped account that is within its grace period).  # noqa: E501

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> future = api.undrop_account_with_http_info(name, async_req=True)
        >>> result = future.result()
        :param name: Identifier (i.e. name) for the resource. (required)
        :type name: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _return_http_data_only: response data without head status code
                                       and headers
        :type _return_http_data_only: bool, optional
        :param _preload_content: if False, the urllib3.HTTPResponse object will
                                 be returned without reading/decoding response
                                 data. Default is True.
        :type _preload_content: bool, optional
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns a Future object representing the execution of the method.
        :rtype: tuple(Union[SuccessResponse, Future[SuccessResponse]], status_code(int), headers(HTTPHeaderDict))
        """
        _params = locals()

        _all_params = ["name"]
        _all_params.extend(
            [
                "async_req",
                "_return_http_data_only",
                "_preload_content",
                "_request_timeout",
                "_request_auth",
                "_content_type",
                "_headers",
            ]
        )

        # validate the arguments
        for _key, _val in _params["kwargs"].items():
            if _key not in _all_params:
                raise _APITypeError(f"Got an unexpected keyword argument '{_key}' to method undrop_account")
            _params[_key] = _val
        del _params["kwargs"]

        _collection_formats = {}

        # process the path parameters
        _path_params = {}

        if _params["name"]:
            _path_params["name"] = _params["name"]

        # process the query parameters
        _query_params = []

        # process the header parameters
        _header_params = dict(_params.get("_headers", {}))

        # process the form parameters
        _form_params = []
        _files = {}

        # process the body parameter
        _body_params = None

        # set the HTTP header `Accept`
        _header_params["Accept"] = self.api_client.select_header_accept(["application/json"])

        # authentication setting
        _auth_settings = ["ExternalOAuth", "KeyPair", "ProgrammaticAccessToken", "SnowflakeOAuth"]

        _response_types_map = {
            "200": "SuccessResponse",
            "202": "SuccessAcceptedResponse",
            "400": "ErrorResponse",
            "401": "ErrorResponse",
            "403": "ErrorResponse",
            "404": "ErrorResponse",
            "405": "ErrorResponse",
            "408": "ErrorResponse",
            "409": "ErrorResponse",
            "410": "ErrorResponse",
            "429": "ErrorResponse",
            "500": "ErrorResponse",
            "503": "ErrorResponse",
            "504": "ErrorResponse",
        }

        return self.api_client.call_api(
            self._root,
            "/api/v2/accounts/{name}:undrop",
            "POST",
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get("async_req"),
            _return_http_data_only=_params.get("_return_http_data_only"),
            _preload_content=_params.get("_preload_content", True),
            _request_timeout=_params.get("_request_timeout"),
            collection_formats=_collection_formats,
            _request_auth=_params.get("_request_auth"),
            _deserialize_response_fn=self.deserialize,
        )

    @overload
    def delete_account(
        self,
        name: Annotated[str, Field(strict=True, description="Identifier (i.e. name) for the resource.")],
        grace_period_in_days: Annotated[
            StrictInt,
            Field(
                description="Specifies the number of days during which the account can be restored (“undropped”). The minimum is 3 days and the maximum is 90 days."
            ),
        ],
        if_exists: Annotated[
            Optional[StrictBool],
            Field(
                description="Parameter that specifies how to handle the request for a resource that does not exist: - `true`: The endpoint does not throw an error if the resource does not exist. It returns a 200 success response, but does not take any action on the resource. - `false`: The endpoint throws an error if the resource doesn't exist."
            ),
        ] = None,
        async_req: Literal[False] = False,
        **kwargs,
    ) -> SuccessResponse: ...

    @overload
    def delete_account(
        self,
        name: Annotated[str, Field(strict=True, description="Identifier (i.e. name) for the resource.")],
        grace_period_in_days: Annotated[
            StrictInt,
            Field(
                description="Specifies the number of days during which the account can be restored (“undropped”). The minimum is 3 days and the maximum is 90 days."
            ),
        ],
        if_exists: Annotated[
            Optional[StrictBool],
            Field(
                description="Parameter that specifies how to handle the request for a resource that does not exist: - `true`: The endpoint does not throw an error if the resource does not exist. It returns a 200 success response, but does not take any action on the resource. - `false`: The endpoint throws an error if the resource doesn't exist."
            ),
        ] = None,
        async_req: Literal[True] = True,
        **kwargs,
    ) -> Future[SuccessResponse]: ...

    @overload
    def delete_account(
        self,
        name: Annotated[str, Field(strict=True, description="Identifier (i.e. name) for the resource.")],
        grace_period_in_days: Annotated[
            StrictInt,
            Field(
                description="Specifies the number of days during which the account can be restored (“undropped”). The minimum is 3 days and the maximum is 90 days."
            ),
        ],
        if_exists: Annotated[
            Optional[StrictBool],
            Field(
                description="Parameter that specifies how to handle the request for a resource that does not exist: - `true`: The endpoint does not throw an error if the resource does not exist. It returns a 200 success response, but does not take any action on the resource. - `false`: The endpoint throws an error if the resource doesn't exist."
            ),
        ] = None,
        async_req: bool = False,
        **kwargs,
    ) -> Union[SuccessResponse, Future[SuccessResponse]]: ...

    @validate_call
    def delete_account(
        self,
        name: Annotated[str, Field(strict=True, description="Identifier (i.e. name) for the resource.")],
        grace_period_in_days: Annotated[
            StrictInt,
            Field(
                description="Specifies the number of days during which the account can be restored (“undropped”). The minimum is 3 days and the maximum is 90 days."
            ),
        ],
        if_exists: Annotated[
            Optional[StrictBool],
            Field(
                description="Parameter that specifies how to handle the request for a resource that does not exist: - `true`: The endpoint does not throw an error if the resource does not exist. It returns a 200 success response, but does not take any action on the resource. - `false`: The endpoint throws an error if the resource doesn't exist."
            ),
        ] = None,
        **kwargs,
    ) -> Union[SuccessResponse, Future[SuccessResponse]]:
        r"""Delete an account.  # noqa: E501

        Deletes the specified account. If you enable the `ifExists` parameter, the operation succeeds even if the account does not exist. Otherwise, a 404 failure is returned if the account does not exist. if the drop is unsuccessful.  # noqa: E501

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> future = api.delete_account(name, grace_period_in_days, if_exists, async_req=True)
        >>> result = future.result()
        :param name: Identifier (i.e. name) for the resource. (required)
        :type name: str
        :param grace_period_in_days: Specifies the number of days during which the account can be restored (“undropped”). The minimum is 3 days and the maximum is 90 days. (required)
        :type grace_period_in_days: int
        :param if_exists: Parameter that specifies how to handle the request for a resource that does not exist: - `true`: The endpoint does not throw an error if the resource does not exist. It returns a 200 success response, but does not take any action on the resource. - `false`: The endpoint throws an error if the resource doesn't exist.
        :type if_exists: bool
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the urllib3.HTTPResponse object will
                                 be returned without reading/decoding response
                                 data. Default is True.
        :type _preload_content: bool, optional
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns a Future object representing the execution of the method.
        :rtype: Union[SuccessResponse, Future[SuccessResponse]]
        """
        kwargs["_return_http_data_only"] = True
        return self.delete_account_with_http_info(name, grace_period_in_days, if_exists, **kwargs)

    @validate_call
    def delete_account_with_http_info(
        self,
        name: Annotated[str, Field(strict=True, description="Identifier (i.e. name) for the resource.")],
        grace_period_in_days: Annotated[
            StrictInt,
            Field(
                description="Specifies the number of days during which the account can be restored (“undropped”). The minimum is 3 days and the maximum is 90 days."
            ),
        ],
        if_exists: Annotated[
            Optional[StrictBool],
            Field(
                description="Parameter that specifies how to handle the request for a resource that does not exist: - `true`: The endpoint does not throw an error if the resource does not exist. It returns a 200 success response, but does not take any action on the resource. - `false`: The endpoint throws an error if the resource doesn't exist."
            ),
        ] = None,
        **kwargs,
    ):
        r"""Delete an account.  # noqa: E501

        Deletes the specified account. If you enable the `ifExists` parameter, the operation succeeds even if the account does not exist. Otherwise, a 404 failure is returned if the account does not exist. if the drop is unsuccessful.  # noqa: E501

        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> future = api.delete_account_with_http_info(name, grace_period_in_days, if_exists, async_req=True)
        >>> result = future.result()
        :param name: Identifier (i.e. name) for the resource. (required)
        :type name: str
        :param grace_period_in_days: Specifies the number of days during which the account can be restored (“undropped”). The minimum is 3 days and the maximum is 90 days. (required)
        :type grace_period_in_days: int
        :param if_exists: Parameter that specifies how to handle the request for a resource that does not exist: - `true`: The endpoint does not throw an error if the resource does not exist. It returns a 200 success response, but does not take any action on the resource. - `false`: The endpoint throws an error if the resource doesn't exist.
        :type if_exists: bool
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _return_http_data_only: response data without head status code
                                       and headers
        :type _return_http_data_only: bool, optional
        :param _preload_content: if False, the urllib3.HTTPResponse object will
                                 be returned without reading/decoding response
                                 data. Default is True.
        :type _preload_content: bool, optional
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns a Future object representing the execution of the method.
        :rtype: tuple(Union[SuccessResponse, Future[SuccessResponse]], status_code(int), headers(HTTPHeaderDict))
        """
        _params = locals()

        _all_params = ["name", "grace_period_in_days", "if_exists"]
        _all_params.extend(
            [
                "async_req",
                "_return_http_data_only",
                "_preload_content",
                "_request_timeout",
                "_request_auth",
                "_content_type",
                "_headers",
            ]
        )

        # validate the arguments
        for _key, _val in _params["kwargs"].items():
            if _key not in _all_params:
                raise _APITypeError(f"Got an unexpected keyword argument '{_key}' to method delete_account")
            _params[_key] = _val
        del _params["kwargs"]

        _collection_formats = {}

        # process the path parameters
        _path_params = {}

        if _params["name"]:
            _path_params["name"] = _params["name"]

        # process the query parameters
        _query_params = []

        if _params.get("if_exists") is not None:
            _query_params.append(("ifExists", _params["if_exists"]))

        if _params.get("grace_period_in_days") is not None:
            _query_params.append(("gracePeriodInDays", _params["grace_period_in_days"]))

        # process the header parameters
        _header_params = dict(_params.get("_headers", {}))

        # process the form parameters
        _form_params = []
        _files = {}

        # process the body parameter
        _body_params = None

        # set the HTTP header `Accept`
        _header_params["Accept"] = self.api_client.select_header_accept(["application/json"])

        # authentication setting
        _auth_settings = ["ExternalOAuth", "KeyPair", "ProgrammaticAccessToken", "SnowflakeOAuth"]

        _response_types_map = {
            "200": "SuccessResponse",
            "202": "SuccessAcceptedResponse",
            "400": "ErrorResponse",
            "401": "ErrorResponse",
            "403": "ErrorResponse",
            "404": "ErrorResponse",
            "405": "ErrorResponse",
            "408": "ErrorResponse",
            "409": "ErrorResponse",
            "410": "ErrorResponse",
            "429": "ErrorResponse",
            "500": "ErrorResponse",
            "503": "ErrorResponse",
            "504": "ErrorResponse",
        }

        return self.api_client.call_api(
            self._root,
            "/api/v2/accounts/{name}",
            "DELETE",
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get("async_req"),
            _return_http_data_only=_params.get("_return_http_data_only"),
            _preload_content=_params.get("_preload_content", True),
            _request_timeout=_params.get("_request_timeout"),
            collection_formats=_collection_formats,
            _request_auth=_params.get("_request_auth"),
            _deserialize_response_fn=self.deserialize,
        )
