"""
This module provides access to the Windows registry API.

Functions:

CloseKey() - Closes a registry key.
ConnectRegistry() - Establishes a connection to a predefined registry handle
                    on another computer.
CreateKey() - Creates the specified key, or opens it if it already exists.
DeleteKey() - Deletes the specified key.
DeleteValue() - Removes a named value from the specified registry key.
DeleteTree() - Deletes the specified key and all its subkeys and values recursively.
EnumKey() - Enumerates subkeys of the specified open registry key.
EnumValue() - Enumerates values of the specified open registry key.
ExpandEnvironmentStrings() - Expand the env strings in a REG_EXPAND_SZ
                             string.
FlushKey() - Writes all the attributes of the specified key to the registry.
LoadKey() - Creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and
            stores registration information from a specified file into that
            subkey.
OpenKey() - Opens the specified key.
OpenKeyEx() - Alias of OpenKey().
QueryValue() - Retrieves the value associated with the unnamed value for a
               specified key in the registry.
QueryValueEx() - Retrieves the type and data for a specified value name
                 associated with an open registry key.
QueryInfoKey() - Returns information about the specified key.
SaveKey() - Saves the specified key, and all its subkeys a file.
SetValue() - Associates a value with a specified key.
SetValueEx() - Stores data in the value field of an open registry key.

Special objects:

HKEYType -- type object for HKEY objects
error -- exception raised for Win32 errors

Integer constants:
Many constants are defined - see the documentation for each function
to see what constants are used, and where.
"""

import sys
from _typeshed import ReadableBuffer, Unused
from types import TracebackType
from typing import Any, Final, Literal, final, overload
from typing_extensions import Self, TypeAlias

if sys.platform == "win32":
    _KeyType: TypeAlias = HKEYType | int
    def CloseKey(hkey: _KeyType, /) -> None: ...
    def ConnectRegistry(computer_name: str | None, key: _KeyType, /) -> HKEYType: ...
    def CreateKey(key: _KeyType, sub_key: str | None, /) -> HKEYType: ...
    def CreateKeyEx(key: _KeyType, sub_key: str | None, reserved: int = 0, access: int = 131078) -> HKEYType: ...
    def DeleteKey(key: _KeyType, sub_key: str, /) -> None: ...
    def DeleteKeyEx(key: _KeyType, sub_key: str, access: int = 256, reserved: int = 0) -> None: ...
    def DeleteValue(key: _KeyType, value: str, /) -> None: ...
    def EnumKey(key: _KeyType, index: int, /) -> str: ...
    def EnumValue(key: _KeyType, index: int, /) -> tuple[str, Any, int]: ...
    def ExpandEnvironmentStrings(string: str, /) -> str: ...
    def FlushKey(key: _KeyType, /) -> None: ...
    def LoadKey(key: _KeyType, sub_key: str, file_name: str, /) -> None: ...
    def OpenKey(key: _KeyType, sub_key: str | None, reserved: int = 0, access: int = 131097) -> HKEYType: ...
    def OpenKeyEx(key: _KeyType, sub_key: str | None, reserved: int = 0, access: int = 131097) -> HKEYType: ...
    def QueryInfoKey(key: _KeyType, /) -> tuple[int, int, int]: ...
    def QueryValue(key: _KeyType, sub_key: str | None, /) -> str: ...
    def QueryValueEx(key: _KeyType, name: str, /) -> tuple[Any, int]: ...
    def SaveKey(key: _KeyType, file_name: str, /) -> None: ...
    def SetValue(key: _KeyType, sub_key: str | None, type: int, value: str, /) -> None: ...
    @overload  # type=REG_DWORD|REG_QWORD
    def SetValueEx(
        key: _KeyType, value_name: str | None, reserved: Unused, type: Literal[4, 5], value: int | None, /
    ) -> None: ...
    @overload  # type=REG_SZ|REG_EXPAND_SZ
    def SetValueEx(
        key: _KeyType, value_name: str | None, reserved: Unused, type: Literal[1, 2], value: str | None, /
    ) -> None: ...
    @overload  # type=REG_MULTI_SZ
    def SetValueEx(
        key: _KeyType, value_name: str | None, reserved: Unused, type: Literal[7], value: list[str] | None, /
    ) -> None: ...
    @overload  # type=REG_BINARY and everything else
    def SetValueEx(
        key: _KeyType,
        value_name: str | None,
        reserved: Unused,
        type: Literal[0, 3, 8, 9, 10, 11],
        value: ReadableBuffer | None,
        /,
    ) -> None: ...
    @overload  # Unknown or undocumented
    def SetValueEx(
        key: _KeyType,
        value_name: str | None,
        reserved: Unused,
        type: int,
        value: int | str | list[str] | ReadableBuffer | None,
        /,
    ) -> None: ...
    def DisableReflectionKey(key: _KeyType, /) -> None: ...
    def EnableReflectionKey(key: _KeyType, /) -> None: ...
    def QueryReflectionKey(key: _KeyType, /) -> bool: ...

    HKEY_CLASSES_ROOT: Final[int]
    HKEY_CURRENT_USER: Final[int]
    HKEY_LOCAL_MACHINE: Final[int]
    HKEY_USERS: Final[int]
    HKEY_PERFORMANCE_DATA: Final[int]
    HKEY_CURRENT_CONFIG: Final[int]
    HKEY_DYN_DATA: Final[int]

    KEY_ALL_ACCESS: Final = 983103
    KEY_WRITE: Final = 131078
    KEY_READ: Final = 131097
    KEY_EXECUTE: Final = 131097
    KEY_QUERY_VALUE: Final = 1
    KEY_SET_VALUE: Final = 2
    KEY_CREATE_SUB_KEY: Final = 4
    KEY_ENUMERATE_SUB_KEYS: Final = 8
    KEY_NOTIFY: Final = 16
    KEY_CREATE_LINK: Final = 32

    KEY_WOW64_64KEY: Final = 256
    KEY_WOW64_32KEY: Final = 512

    REG_BINARY: Final = 3
    REG_DWORD: Final = 4
    REG_DWORD_LITTLE_ENDIAN: Final = 4
    REG_DWORD_BIG_ENDIAN: Final = 5
    REG_EXPAND_SZ: Final = 2
    REG_LINK: Final = 6
    REG_MULTI_SZ: Final = 7
    REG_NONE: Final = 0
    REG_QWORD: Final = 11
    REG_QWORD_LITTLE_ENDIAN: Final = 11
    REG_RESOURCE_LIST: Final = 8
    REG_FULL_RESOURCE_DESCRIPTOR: Final = 9
    REG_RESOURCE_REQUIREMENTS_LIST: Final = 10
    REG_SZ: Final = 1

    REG_CREATED_NEW_KEY: Final = 1  # undocumented
    REG_LEGAL_CHANGE_FILTER: Final = 268435471  # undocumented
    REG_LEGAL_OPTION: Final = 31  # undocumented
    REG_NOTIFY_CHANGE_ATTRIBUTES: Final = 2  # undocumented
    REG_NOTIFY_CHANGE_LAST_SET: Final = 4  # undocumented
    REG_NOTIFY_CHANGE_NAME: Final = 1  # undocumented
    REG_NOTIFY_CHANGE_SECURITY: Final = 8  # undocumented
    REG_NO_LAZY_FLUSH: Final = 4  # undocumented
    REG_OPENED_EXISTING_KEY: Final = 2  # undocumented
    REG_OPTION_BACKUP_RESTORE: Final = 4  # undocumented
    REG_OPTION_CREATE_LINK: Final = 2  # undocumented
    REG_OPTION_NON_VOLATILE: Final = 0  # undocumented
    REG_OPTION_OPEN_LINK: Final = 8  # undocumented
    REG_OPTION_RESERVED: Final = 0  # undocumented
    REG_OPTION_VOLATILE: Final = 1  # undocumented
    REG_REFRESH_HIVE: Final = 2  # undocumented
    REG_WHOLE_HIVE_VOLATILE: Final = 1  # undocumented

    error = OSError

    # Though this class has a __name__ of PyHKEY, it's exposed as HKEYType for some reason
    @final
    class HKEYType:
        def __bool__(self) -> bool: ...
        def __int__(self) -> int: ...
        def __enter__(self) -> Self: ...
        def __exit__(
            self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, /
        ) -> bool | None: ...
        def Close(self) -> None: ...
        def Detach(self) -> int: ...
        def __hash__(self) -> int: ...
        @property
        def handle(self) -> int: ...
