

import multiprocessing
import os
from typing import BinaryIO, Optional, Union

import fsspec

from .. import Dataset, Features, NamedSplit, config
from ..formatting import query_table
from ..packaged_modules.json.json import Json
from ..utils import logging
from ..utils.typing import NestedDataStructureLike, PathLike
from .abc import AbstractDatasetReader


class    A__ ( lowercase_     ):



    def __init__(   self						,			UpperCamelCase__						,			UpperCamelCase__ = None						,			UpperCamelCase__ = None						,			UpperCamelCase__ = None						,			UpperCamelCase__ = False						,			UpperCamelCase__ = False						,			UpperCamelCase__ = None						,			UpperCamelCase__ = None						,			**UpperCamelCase__						,			)  -> Tuple:





           '''simple docstring'''
           super().__init__(
               a__						,			split=a__						,			features=a__						,			cache_dir=a__						,			keep_in_memory=a__						,			streaming=a__						,			num_proc=a__						,			**a__						,			)
           A_		   = field
           A_		   = path_or_paths if isinstance(a__						,			a__    ) else {self.split: path_or_paths}
           A_		   = Json(
               cache_dir=a__						,			data_files=a__						,			features=a__						,			field=a__						,			**a__						,			)







    def    snake_case_     (   self    )  -> List[Any]:





           '''simple docstring'''




           if self.streaming:
                  A_		   = self.builder.as_streaming_dataset(split=self.split    )
           # Build regular (map-style) dataset
           else:
                  A_		   = None
                  A_		   = None
                  A_		   = None
                  A_		   = None

                  self.builder.download_and_prepare(
                      download_config=a__						,			download_mode=a__						,			verification_mode=a__						,			base_path=a__						,			num_proc=self.num_proc						,			)
                  A_		   = self.builder.as_dataset(
                      split=self.split						,			verification_mode=a__						,			in_memory=self.keep_in_memory    )
           return dataset


class    A__ :



    def __init__(   self						,			UpperCamelCase__						,			UpperCamelCase__						,			UpperCamelCase__ = None						,			UpperCamelCase__ = None						,			**UpperCamelCase__						,			)  -> Optional[int]:





           '''simple docstring'''




           if num_proc is not None and num_proc <= 0:
                  raise ValueError(f'''num_proc {num_proc} must be an integer > 0.'''    )

           A_		   = dataset
           A_		   = path_or_buf
           A_		   = batch_size if batch_size else config.DEFAULT_MAX_BATCH_SIZE
           A_		   = num_proc
           A_		   = """utf-8"""
           A_		   = to_json_kwargs



    def    snake_case_     (   self    )  -> int:





           '''simple docstring'''
           A_		   = self.to_json_kwargs.pop("""path_or_buf"""						,			a__    )
           A_		   = self.to_json_kwargs.pop("""orient"""						,			"""records"""    )
           A_		   = self.to_json_kwargs.pop("""lines"""						,			True if orient == """records""" else False    )
           A_		   = self.to_json_kwargs.pop("""index"""						,			False if orient in ["""split""", """table"""] else True    )
           A_		   = self.to_json_kwargs.pop("""compression"""						,			a__    )

           if compression not in [None, "infer", "gzip", "bz2", "xz"]:
                  raise NotImplementedError(f'''`datasets` currently does not support {compression} compression'''    )

           if isinstance(self.path_or_buf						,			(str, bytes, os.PathLike)    ):
                  with fsspec.open(self.path_or_buf						,			"""wb"""						,			compression=a__    ) as buffer:
                         A_		   = self._write(file_obj=a__						,			orient=a__						,			lines=a__						,			index=a__						,			**self.to_json_kwargs    )
           else:
                  if compression:
                         raise NotImplementedError(
                             f'''The compression parameter is not supported when writing to a buffer, but compression={compression}'''
                             """ was passed. Please provide a local path instead."""    )
                  A_		   = self._write(
                      file_obj=self.path_or_buf						,			orient=a__						,			lines=a__						,			index=a__						,			**self.to_json_kwargs    )
           return written



    def    snake_case_     (   self						,			UpperCamelCase__    )  -> Optional[int]:





           '''simple docstring'''
           A_   ,     A_   ,     A_   ,     A_   ,     A_		   = args

           A_		   = query_table(
               table=self.dataset.data						,			key=slice(a__						,			offset + self.batch_size    )						,			indices=self.dataset._indices						,			)
           A_		   = batch.to_pandas().to_json(
               path_or_buf=a__						,			orient=a__						,			lines=a__						,			index=a__						,			**a__    )
           if not json_str.endswith("""\n"""    ):
                  json_str += "\n"
           return json_str.encode(self.encoding    )







    def    snake_case_     (   self						,			UpperCamelCase__						,			UpperCamelCase__						,			UpperCamelCase__						,			UpperCamelCase__						,			**UpperCamelCase__						,			)  -> int:





           '''simple docstring'''
           A_		   = 0

           if self.num_proc is None or self.num_proc == 1:
                  for offset in logging.tqdm(
                      range(0						,			len(self.dataset    )						,			self.batch_size    )						,			unit="""ba"""						,			disable=not logging.is_progress_bar_enabled()						,			desc="""Creating json from Arrow format"""						,			):
                         A_		   = self._batch_json((offset, orient, lines, index, to_json_kwargs)    )
                         written += file_obj.write(a__    )
           else:
                  A_   ,     A_		   = len(self.dataset    ), self.batch_size
                  with multiprocessing.Pool(self.num_proc    ) as pool:
                         for json_str in logging.tqdm(
                             pool.imap(
                                 self._batch_json						,			[(offset, orient, lines, index, to_json_kwargs) for offset in range(0						,			a__						,			a__    )]						,			)						,			total=(num_rows // batch_size) + 1 if num_rows % batch_size else num_rows // batch_size						,			unit="""ba"""						,			disable=not logging.is_progress_bar_enabled()						,			desc="""Creating json from Arrow format"""						,			):
                                written += file_obj.write(a__    )

           return written



'''simple docstring'''







from functools import lru_cache
@lru_cache
def  UpperCAmelCase__      ( UpperCAmelCase__			)     ->     int:
       if num < 0:
              raise ValueError("""Number should not be negative."""			)

       return 1 if num in (0, 1) else num * factorial(num - 1			)


if __name__ == "__main__":
      import doctest

      doctest.testmod()
