'''simple docstring'''

import importlib
import os
import platform
from pathlib import Path

from packaging import version

from .utils.logging import get_logger


__snake_case       :   Dict  		=    get_logger(__name__)

# Datasets
__snake_case       :   Union[str, Any]  		=    '''https://s3.amazonaws.com/datasets.huggingface.co/datasets/datasets'''
__snake_case       :   Optional[int]  		=    '''https://cdn-datasets.huggingface.co/datasets/datasets'''
__snake_case       :   Any  		=    '''https://raw.githubusercontent.com/huggingface/datasets/{revision}/datasets/{path}/{name}'''

# Metrics
__snake_case       :   str  		=    '''https://s3.amazonaws.com/datasets.huggingface.co/datasets/metrics'''
__snake_case       :   str  		=    '''https://cdn-datasets.huggingface.co/datasets/metric'''
__snake_case       :   Dict  		=    '''https://raw.githubusercontent.com/huggingface/datasets/{revision}/metrics/{path}/{name}'''

# Hub
__snake_case       :   Tuple  		=    os.environ.get('''HF_ENDPOINT''', '''https://huggingface.co''')
__snake_case       :   Any  		=    HF_ENDPOINT + '''/datasets/{repo_id}/resolve/{revision}/{path}'''
__snake_case       :   Optional[int]  		=    '''main'''

__snake_case       :   List[str]  		=    version.parse(platform.python_version())

if PY_VERSION < version.parse('''3.8'''):
      import importlib_metadata
else:
      import importlib.metadata as importlib_metadata

# General environment variables accepted values for booleans
__snake_case       :   Optional[Any]  		=    {'''1''', '''ON''', '''YES''', '''TRUE'''}
__snake_case       :   Optional[Any]  		=    ENV_VARS_TRUE_VALUES.union({'''AUTO'''})


# Imports
__snake_case       :   str  		=    version.parse(importlib_metadata.version('''dill'''))
__snake_case       :   List[Any]  		=    version.parse(importlib_metadata.version('''pandas'''))
__snake_case       :   Any  		=    version.parse(importlib_metadata.version('''pyarrow'''))

__snake_case       :   Union[str, Any]  		=    os.environ.get('''USE_TF''', '''AUTO''').upper()
__snake_case       :   int  		=    os.environ.get('''USE_TORCH''', '''AUTO''').upper()
__snake_case       :   Optional[int]  		=    os.environ.get('''USE_JAX''', '''AUTO''').upper()

__snake_case       :   Any  		=    '''N/A'''
__snake_case       :   Tuple  		=    False

if USE_TORCH in ENV_VARS_TRUE_AND_AUTO_VALUES and USE_TF not in ENV_VARS_TRUE_VALUES:
      __snake_case       :   List[Any]  		=    importlib.util.find_spec('''torch''') is not None
      if TORCH_AVAILABLE:
            try:
                  __snake_case       :   Union[str, Any]  		=    version.parse(importlib_metadata.version('''torch'''))
                  logger.info(F'''PyTorch version {TORCH_VERSION} available.''')
            except importlib_metadata.PackageNotFoundError:
                  pass
else:
      logger.info('''Disabling PyTorch because USE_TF is set''')

__snake_case       :   List[Any]  		=    '''N/A'''
__snake_case       :   str  		=    False

if USE_TF in ENV_VARS_TRUE_AND_AUTO_VALUES and USE_TORCH not in ENV_VARS_TRUE_VALUES:
      __snake_case       :   int  		=    importlib.util.find_spec('''tensorflow''') is not None
      if TF_AVAILABLE:
            # For the metadata, we have to look for both tensorflow and tensorflow-cpu
            for package in [
                "tensorflow",
                "tensorflow-cpu",
                "tensorflow-gpu",
                "tf-nightly",
                "tf-nightly-cpu",
                "tf-nightly-gpu",
                "intel-tensorflow",
                "tensorflow-rocm",
                "tensorflow-macos",
            ]:
                  try:
                        __snake_case       :   List[str]  		=    version.parse(importlib_metadata.version(package))
                  except importlib_metadata.PackageNotFoundError:
                        continue
                  else:
                        break
            else:
                  __snake_case       :   str  		=    False
      if TF_AVAILABLE:
            if TF_VERSION.major < 2:
                  logger.info(F'''TensorFlow found but with version {TF_VERSION}. `datasets` requires version 2 minimum.''')
                  __snake_case       :   List[Any]  		=    False
            else:
                  logger.info(F'''TensorFlow version {TF_VERSION} available.''')
else:
      logger.info('''Disabling Tensorflow because USE_TORCH is set''')


__snake_case       :   int  		=    '''N/A'''
__snake_case       :   Union[str, Any]  		=    False

if USE_JAX in ENV_VARS_TRUE_AND_AUTO_VALUES:
      __snake_case       :   Optional[Any]  		=    importlib.util.find_spec('''jax''') is not None and importlib.util.find_spec('''jaxlib''') is not None
      if JAX_AVAILABLE:
            try:
                  __snake_case       :   List[Any]  		=    version.parse(importlib_metadata.version('''jax'''))
                  logger.info(F'''JAX version {JAX_VERSION} available.''')
            except importlib_metadata.PackageNotFoundError:
                  pass
else:
      logger.info('''Disabling JAX because USE_JAX is set to False''')


__snake_case       :   List[str]  		=    os.environ.get('''USE_BEAM''', '''AUTO''').upper()
__snake_case       :   Dict  		=    '''N/A'''
__snake_case       :   List[str]  		=    False
if USE_BEAM in ENV_VARS_TRUE_AND_AUTO_VALUES:
      try:
            __snake_case       :   Tuple  		=    version.parse(importlib_metadata.version('''apache_beam'''))
            __snake_case       :   int  		=    True
            logger.info(F'''Apache Beam version {BEAM_VERSION} available.''')
      except importlib_metadata.PackageNotFoundError:
            pass
else:
      logger.info('''Disabling Apache Beam because USE_BEAM is set to False''')


# Optional tools for data loading
__snake_case       :   List[str]  		=    importlib.util.find_spec('''sqlalchemy''') is not None

# Optional tools for feature decoding
__snake_case       :   Optional[Any]  		=    importlib.util.find_spec('''PIL''') is not None
__snake_case       :   Optional[Any]  		=    importlib.util.find_spec('''soundfile''') is not None and version.parse(
    importlib.import_module('''soundfile''').__libsndfile_version__
) >= version.parse('''1.0.31''')
__snake_case       :   Union[str, Any]  		=    importlib.util.find_spec('''soundfile''') is not None and version.parse(
    importlib.import_module('''soundfile''').__libsndfile_version__
) >= version.parse('''1.1.0''')

# Optional compression tools
__snake_case       :   int  		=    importlib.util.find_spec('''rarfile''') is not None
__snake_case       :   Union[str, Any]  		=    importlib.util.find_spec('''zstandard''') is not None
__snake_case       :   Optional[int]  		=    importlib.util.find_spec('''lz4''') is not None
__snake_case       :   Any  		=    importlib.util.find_spec('''py7zr''') is not None


# Cache location
__snake_case       :   Dict  		=    '''~/.cache'''
__snake_case       :   int  		=    os.getenv('''XDG_CACHE_HOME''', DEFAULT_XDG_CACHE_HOME)
__snake_case       :   Union[str, Any]  		=    os.path.join(XDG_CACHE_HOME, '''huggingface''')
__snake_case       :   List[Any]  		=    os.path.expanduser(os.getenv('''HF_HOME''', DEFAULT_HF_CACHE_HOME))

__snake_case       :   List[str]  		=    os.path.join(HF_CACHE_HOME, '''datasets''')
__snake_case       :   List[Any]  		=    Path(os.getenv('''HF_DATASETS_CACHE''', DEFAULT_HF_DATASETS_CACHE))

__snake_case       :   str  		=    os.path.join(HF_CACHE_HOME, '''metrics''')
__snake_case       :   int  		=    Path(os.getenv('''HF_METRICS_CACHE''', DEFAULT_HF_METRICS_CACHE))

__snake_case       :   Optional[int]  		=    os.path.join(HF_CACHE_HOME, '''modules''')
__snake_case       :   List[Any]  		=    Path(os.getenv('''HF_MODULES_CACHE''', DEFAULT_HF_MODULES_CACHE))

__snake_case       :   Dict  		=    '''downloads'''
__snake_case       :   Optional[Any]  		=    os.path.join(HF_DATASETS_CACHE, DOWNLOADED_DATASETS_DIR)
__snake_case       :   int  		=    Path(os.getenv('''HF_DATASETS_DOWNLOADED_DATASETS_PATH''', DEFAULT_DOWNLOADED_DATASETS_PATH))

__snake_case       :   Optional[Any]  		=    '''extracted'''
__snake_case       :   Dict  		=    os.path.join(DEFAULT_DOWNLOADED_DATASETS_PATH, EXTRACTED_DATASETS_DIR)
__snake_case       :   int  		=    Path(os.getenv('''HF_DATASETS_EXTRACTED_DATASETS_PATH''', DEFAULT_EXTRACTED_DATASETS_PATH))

# Download count for the website
__snake_case       :   Union[str, Any]  		=    (
    os.environ.get('''HF_UPDATE_DOWNLOAD_COUNTS''', '''AUTO''').upper() in ENV_VARS_TRUE_AND_AUTO_VALUES
)

# Batch size constants. For more info, see:
# https://github.com/apache/arrow/blob/master/docs/source/cpp/arrays.rst#size-limitations-and-recommendations)
__snake_case       :   Tuple  		=    10_00

# Size of the preloaded record batch in `Dataset.__iter__`
__snake_case       :   str  		=    10

# Pickling tables works only for small tables (<4GiB)
# For big tables, we write them on disk instead
__snake_case       :   Optional[Any]  		=    4 << 30

# Max shard size in bytes (e.g. to shard parquet datasets in push_to_hub or download_and_prepare)
__snake_case       :   Optional[Any]  		=    '''500MB'''

# Parquet configuration
__snake_case       :   Optional[Any]  		=    1_00
__snake_case       :   Optional[int]  		=    1_00
__snake_case       :   int  		=    1_00

# Offline mode
__snake_case       :   List[Any]  		=    os.environ.get('''HF_DATASETS_OFFLINE''', '''AUTO''').upper() in ENV_VARS_TRUE_VALUES

# In-memory
__snake_case       :   List[Any]  		=    0  # Disabled
__snake_case       :   Dict  		=    float(os.environ.get('''HF_DATASETS_IN_MEMORY_MAX_SIZE''', DEFAULT_IN_MEMORY_MAX_SIZE))

# File names
__snake_case       :   List[Any]  		=    '''dataset.arrow'''
__snake_case       :   Optional[Any]  		=    '''indices.arrow'''
__snake_case       :   List[str]  		=    '''state.json'''
__snake_case       :   Optional[int]  		=    '''dataset_info.json'''
__snake_case       :   Dict  		=    '''dataset_infos.json'''
__snake_case       :   List[Any]  		=    '''LICENSE'''
__snake_case       :   Optional[int]  		=    '''metric_info.json'''
__snake_case       :   int  		=    '''dataset_dict.json'''

__snake_case       :   int  		=    '''datasets_modules'''

__snake_case       :   str  		=    2_55

# Streaming
__snake_case       :   Union[str, Any]  		=    20
__snake_case       :   Dict  		=    5

# Datasets without script
__snake_case       :   Optional[Any]  		=    2_00
__snake_case       :   Tuple  		=    10
__snake_case       :   Tuple  		=    2_00

# Progress bars
__snake_case       :   List[str]  		=    0.05  # 20 progress updates per sec

'''simple docstring'''

import os
import sys

from . import rsa_key_generator as rkg

__snake_case       :   Dict  		=    1_28
__snake_case       :   Union[str, Any]  		=    2_56



def lowerCamelCase__						(       A_       ,			A_ = DEFAULT_BLOCK_SIZE       ):
 UpperCAmelCase_				       =					message.encode("ascii"       )

 UpperCAmelCase_				       =					[]
 for block_start in range(0       ,			len(A_       )       ,			A_       ):
  UpperCAmelCase_				       =					0
  for i in range(A_       ,			min(block_start + block_size       ,			len(A_       )       )       ):
   block_int += message_bytes[i] * (BYTE_SIZE ** (i % block_size))
  block_ints.append(A_       )
 return block_ints



def lowerCamelCase__						(       A_       ,			A_       ,			A_ = DEFAULT_BLOCK_SIZE       ):
 UpperCAmelCase_				       =					[]
 for block_int in block_ints:
  UpperCAmelCase_				       =					[]
  for i in range(block_size - 1       ,			-1       ,			-1       ):
   if len(A_       ) + i < message_length:
    UpperCAmelCase_				       =					block_int // (BYTE_SIZE**i)
    UpperCAmelCase_				       =					block_int % (BYTE_SIZE**i)
    block_message.insert(0       ,			chr(A_       )       )
  message.extend(A_       )
 return "".join(A_       )



def lowerCamelCase__						(       A_       ,			A_       ,			A_ = DEFAULT_BLOCK_SIZE       ):
 UpperCAmelCase_				       =					[]
 UpperCAmelCase_       ,       UpperCAmelCase_				       =					key

 for block in get_blocks_from_text(A_       ,			A_       ):
  encrypted_blocks.append(pow(A_       ,			A_       ,			A_       )       )
 return encrypted_blocks



def lowerCamelCase__						(       A_       ,			A_       ,			A_       ,			A_ = DEFAULT_BLOCK_SIZE       ,			):
 UpperCAmelCase_				       =					[]
 UpperCAmelCase_       ,       UpperCAmelCase_				       =					key
 for block in encrypted_blocks:
  decrypted_blocks.append(pow(A_       ,			A_       ,			A_       )       )
 return get_text_from_blocks(A_       ,			A_       ,			A_       )



def lowerCamelCase__						(       A_       ):
 with open(A_       ) as fo:
  UpperCAmelCase_				       =					fo.read()
 UpperCAmelCase_       ,       UpperCAmelCase_       ,       UpperCAmelCase_				       =					content.split(","       )
 return (int(A_       ), int(A_       ), int(A_       ))



def lowerCamelCase__						(       A_       ,			A_       ,			A_       ,			A_ = DEFAULT_BLOCK_SIZE       ,			):
 UpperCAmelCase_       ,       UpperCAmelCase_       ,       UpperCAmelCase_				       =					read_key_file(A_       )
 if key_size < block_size * 8:
  sys.exit(
      "ERROR: Block size is {} bits and key size is {} bits. The RSA cipher "
      "requires the block size to be equal to or greater than the key size. "
      "Either decrease the block size or use different keys.".format(
          block_size * 8       ,			A_       )       )

 UpperCAmelCase_				       =					[str(A_       ) for i in encrypt_message(A_       ,			(n, e)       ,			A_       )]

 UpperCAmelCase_				       =					",".join(A_       )
 UpperCAmelCase_				       =					F"""{len(A_       )}_{block_size}_{encrypted_content}"""
 with open(A_       ,			"w"       ) as fo:
  fo.write(A_       )
 return encrypted_content



def lowerCamelCase__						(       A_       ,			A_       ):
 UpperCAmelCase_       ,       UpperCAmelCase_       ,       UpperCAmelCase_				       =					read_key_file(A_       )
 with open(A_       ) as fo:
  UpperCAmelCase_				       =					fo.read()
 UpperCAmelCase_       ,       UpperCAmelCase_       ,       UpperCAmelCase_				       =					content.split("_"       )
 UpperCAmelCase_				       =					int(A_       )
 UpperCAmelCase_				       =					int(A_       )

 if key_size < block_size * 8:
  sys.exit(
      "ERROR: Block size is {} bits and key size is {} bits. The RSA cipher "
      "requires the block size to be equal to or greater than the key size. "
      "Did you specify the correct key file and encrypted file?".format(
          block_size * 8       ,			A_       )       )

 UpperCAmelCase_				       =					[]
 for block in encrypted_message.split(","       ):
  encrypted_blocks.append(int(A_       )       )

 return decrypt_message(A_       ,			A_       ,			(n, d)       ,			A_       )



def lowerCamelCase__						(       ):
 UpperCAmelCase_				       =					"encrypted_file.txt"
 UpperCAmelCase_				       =					input(R"Encrypt\Decrypt [e\d]: "       )

 if response.lower().startswith("e"       ):
  UpperCAmelCase_				       =					"encrypt"
 elif response.lower().startswith("d"       ):
  UpperCAmelCase_				       =					"decrypt"

 if mode == "encrypt":
  if not os.path.exists("rsa_pubkey.txt"       ):
   rkg.make_key_files("rsa"       ,			1_024       )

  UpperCAmelCase_				       =					input("\nEnter message: "       )
  UpperCAmelCase_				       =					"rsa_pubkey.txt"
  print(F"""Encrypting and writing to {filename}..."""       )
  UpperCAmelCase_				       =					encrypt_and_write_to_file(A_       ,			A_       ,			A_       )

  print("\nEncrypted text:"       )
  print(A_       )

 elif mode == "decrypt":
  UpperCAmelCase_				       =					"rsa_privkey.txt"
  print(F"""Reading from {filename} and decrypting..."""       )
  UpperCAmelCase_				       =					read_from_file_and_decrypt(A_       ,			A_       )
  print("writing decryption to rsa_decryption.txt..."       )
  with open("rsa_decryption.txt"       ,			"w"       ) as dec:
   dec.write(A_       )

  print("\nDecryption:"       )
  print(A_       )


if __name__ == "__main__":
      main()
