
import logging
from pathlib import Path
from typing import Any, List, Tuple

import yaml


# loading package files: https://stackoverflow.com/a/20885799
try:
							import importlib.resources as pkg_resources
except ImportError:
							# Try backported to PY<37 `importlib_resources`.
							import importlib_resources as pkg_resources

from . import resources


lowerCamelCase_  :       str					      =     """https://github.com/huggingface/datasets/tree/main/src/datasets/utils"""
lowerCamelCase_  :       str					      =     F"""{BASE_REF_URL}/{__file__}"""
lowerCamelCase_  :       str					      =     logging.getLogger(__name__)







def 				A__    (  lowerCamelCase  )     ->		Tuple[Any, str]:
				UpperCamelCase_:							List[Any]		=  pkg_resources.read_text(lowerCamelCase   ,			lowerCamelCase  )
				return yaml.safe_load(lowerCamelCase  ), F'''{BASE_REF_URL}/resources/{resource}'''


lowerCamelCase_      ,				lowerCamelCase_  :       Optional[Any]					      =     load_yaml_resource("""readme_structure.yaml""")

lowerCamelCase_  :       Any					      =     [
    """[Needs More Information]""",
    """[More Information Needed]""",
    """(https://github.com/huggingface/datasets/blob/main/CONTRIBUTING.md#how-to-contribute-to-the-dataset-cards)""",
]

# Dictionary representation of section/readme, error_list, warning_list
lowerCamelCase_  :       str					      =     Tuple[dict, List[str], List[str]]

class 				_UpperCamelCase :






			'''simple docstring'''

			def __init__(				self       :				Optional[int]  ,		snake_case_       :				str  ,		snake_case_       :				str  ,		snake_case_       :				List[str] = None  ,		snake_case_       :				bool = False					):
							UpperCamelCase_:							Optional[Any]		=  name
							UpperCamelCase_:							Optional[Any]		=  level
							UpperCamelCase_:							List[str]		=  lines
							UpperCamelCase_:							int		=  """"""
							UpperCamelCase_:							List[str]		=  True
							UpperCamelCase_:							str		=  {}
							UpperCamelCase_:							List[str]		=  []
							UpperCamelCase_:							List[str]		=  []
							if self.lines is not None:
											self.parse(suppress_parsing_errors=snake_case_					)

			def 					lowerCAmelCase__		(				self       :				Dict  ,		snake_case_       :				bool = False					):
							UpperCamelCase_:							Any		=  """"""
							UpperCamelCase_:							Tuple		=  []
							UpperCamelCase_:							Optional[Any]		=  False
							for line in self.lines:
											if line.strip(""" \n"""					) == "":
															continue
											elif line.strip(""" \n"""					)[:3] == "```":
															UpperCamelCase_:							Tuple		=  not code_start
											elif line.split()[0] == self.level + "#" and not code_start:
															if current_sub_level != "":
																			UpperCamelCase_:							Tuple		=  Section(snake_case_  ,		self.level + """#"""  ,		snake_case_					)
																			UpperCamelCase_:							Dict		=  []
															else:
																			if current_lines != []:
																							self.text += "".join(snake_case_					).strip()
																							if self.text != "" and self.text not in FILLER_TEXT:
																											UpperCamelCase_:							str		=  False
																							UpperCamelCase_:							List[str]		=  []

															UpperCamelCase_:							int		=  """ """.join(line.split()[1:]					).strip(""" \n"""					)
											else:
															current_lines.append(snake_case_					)
							else:
											if current_sub_level != "":
															if current_sub_level in self.content:
																			self.parsing_error_list.append(
																			    f'''Multiple sections with the same heading `{current_sub_level}` have been found. Please keep only one of these sections.'''					)
															UpperCamelCase_:							List[Any]		=  Section(snake_case_  ,		self.level + """#"""  ,		snake_case_					)
											else:
															if current_lines != []:
																			self.text += "".join(snake_case_					).strip()
																			if self.text != "" and self.text not in FILLER_TEXT:
																							UpperCamelCase_:							Dict		=  False

							if self.level == "" and not suppress_parsing_errors:
											if self.parsing_error_list != [] or self.parsing_warning_list != []:
															UpperCamelCase_:							Union[str, Any]		=  """\n""".join("""-\t""" + x for x in self.parsing_error_list + self.parsing_warning_list					)
															UpperCamelCase_:							List[Any]		=  f'''The following issues were found while parsing the README at `{self.name}`:\n''' + errors
															raise ValueError(snake_case_					)

			def 					lowerCAmelCase__		(				self       :				Tuple  ,		snake_case_       :				dict					):
							UpperCamelCase_:							List[Any]		=  []
							UpperCamelCase_:							str		=  []
							if structure["allow_empty"] is False:
											# If content is expected
											if self.is_empty_text and self.content == {}:
															# If no content is found, mention it in the error_list
															error_list.append(f'''Expected some content in section `{self.name}` but it is empty.'''					)

							if structure["allow_empty_text"] is False:
											# If some text is expected
											if self.is_empty_text:
															# If no text is found, mention it in the error_list
															error_list.append(
															    f'''Expected some text in section `{self.name}` but it is empty (text in subsections are ignored).'''					)
        # Subsections Validation
							if structure["subsections"] is not None:
											# If subsections are expected
											if self.content == {}:
															# If no subsections are present
															UpperCamelCase_:							List[str]		=  [subsection["""name"""] for subsection in structure["""subsections"""]]
															# Mention the expected values in the error_list
															error_list.append(
															    f'''Section `{self.name}` expected the following subsections: {", ".join(["`"+x+"`" for x in values]					)}. Found \'None\'.'''					)
											else:
															# If some subsections are present
															UpperCamelCase_:							int		=  [subsection["""name"""] for subsection in structure["""subsections"""]]
															UpperCamelCase_:							int		=  False
															for idx, name in enumerate(snake_case_					):
																			if name not in self.content:
																							# If the expected subsection is not present
																							error_list.append(f'''Section `{self.name}` is missing subsection: `{name}`.'''					)
																							UpperCamelCase_:							Optional[int]		=  True
																			else:
																							# If the subsection is present, validate subsection, return the result
																							# and concat the errors from subsection to section error_list

																							# Skip sublevel validation if current level is `###`
																							if self.level == "###":
																											continue
																							else:
																											UpperCamelCase_,      UpperCamelCase_,      UpperCamelCase_:							int		=  self.content[name].validate(
																											    structure["""subsections"""][idx]					)
																							error_list += subsec_error_list
																							warning_list += subsec_warning_list

															if has_missing_subsections:  # we only allow to have extra subsections if all the other ones are here
																			for name in self.content:
																							if name not in structure_names:
																											# If an extra subsection is present
																											warning_list.append(
																											    f'''`{self.name}` has an extra subsection: `{name}`. Skipping further validation checks for this subsection as expected structure is unknown.'''					)
							if error_list:
											# If there are errors, do not return the dictionary as it is invalid
											return {}, error_list, warning_list
							else:
											return self.to_dict(), error_list, warning_list




			def 					lowerCAmelCase__		(				self       :				Any					):
							return {
							    "name": self.name,
							    "text": self.text,
							    "is_empty_text": self.is_empty_text,
							    "subsections": [value.to_dict() for value in self.content.values()],
							}




class 				_UpperCamelCase (    _A     ):  # Level 0






			'''simple docstring'''

			def __init__(				self       :				Tuple  ,		snake_case_       :				str  ,		snake_case_       :				List[str]  ,		snake_case_       :				dict = None  ,		snake_case_       :				bool = False					):
							super().__init__(name=snake_case_  ,		level=""""""					)  # Not using lines here as we need to use a child class parse
							UpperCamelCase_:							Union[str, Any]		=  structure
							UpperCamelCase_:							Optional[Any]		=  -2
							UpperCamelCase_:							str		=  0
							UpperCamelCase_:							Tuple		=  lines
							if self.lines is not None:
											self.parse(suppress_parsing_errors=snake_case_					)

			def 					lowerCAmelCase__		(				self       :				Optional[int]					):
							if self.structure is None:
											UpperCamelCase_,      UpperCamelCase_,      UpperCamelCase_:							List[Any]		=  self._validate(snake_case_					)
							else:
											UpperCamelCase_,      UpperCamelCase_,      UpperCamelCase_:							Optional[Any]		=  self._validate(self.structure					)
							if error_list != [] or warning_list != []:
											UpperCamelCase_:							Any		=  """\n""".join(["""-\t""" + x for x in error_list + warning_list]					)
											UpperCamelCase_:							List[str]		=  f'''The following issues were found for the README at `{self.name}`:\n''' + errors
											raise ValueError(snake_case_					)

			@classmethod
			def 					lowerCAmelCase__		(				cls       :				Tuple  ,		snake_case_       :				Path  ,		snake_case_       :				dict = None  ,		snake_case_       :				bool = False					):
							with open(snake_case_  ,		encoding="""utf-8"""					) as f:
											UpperCamelCase_:							List[str]		=  f.readlines()
							return cls(snake_case_  ,		snake_case_  ,		snake_case_  ,		suppress_parsing_errors=snake_case_					)

			@classmethod
			def 					lowerCAmelCase__		(				cls       :				Optional[Any]  ,		snake_case_       :				str  ,		snake_case_       :				dict = None  ,		snake_case_       :				str = "root"  ,		snake_case_       :				bool = False					):
							UpperCamelCase_:							str		=  string.split("""\n"""					)
							return cls(snake_case_  ,		snake_case_  ,		snake_case_  ,		suppress_parsing_errors=snake_case_					)

			def 					lowerCAmelCase__		(				self       :				Dict  ,		snake_case_       :				bool = False					):
							# Skip Tags
							UpperCamelCase_:							Optional[Any]		=  0

							for line in self.lines:
											self.yaml_tags_line_count += 1
											if line.strip(""" \n"""					) == "---":
															self.tag_count += 1
															if self.tag_count == 2:
																			break
											line_count += 1
							if self.tag_count == 2:
											UpperCamelCase_:							Optional[Any]		=  self.lines[line_count + 1 :]  # Get the last + 1 th item.
							else:
											UpperCamelCase_:							Dict		=  self.lines[self.tag_count :]
							super().parse(suppress_parsing_errors=snake_case_					)

			def __str__(				self       :				Dict					):
							return str(self.to_dict()					)




			def 					lowerCAmelCase__		(				self       :				List[Any]  ,		snake_case_       :				Union[str, Any]					):
							UpperCamelCase_:							List[str]		=  []
							UpperCamelCase_:							int		=  []
							if self.yaml_tags_line_count == 0:
											warning_list.append("""Empty YAML markers are present in the README."""					)
							elif self.tag_count == 0:
											warning_list.append("""No YAML markers are present in the README."""					)
							elif self.tag_count == 1:
											warning_list.append("""Only the start of YAML tags present in the README."""					)
							# Check how many first level sections are present.
							UpperCamelCase_:							Optional[Any]		=  len(self.content.keys()					)
							if num_first_level_keys > 1:
											# If more than one, add to the error list, continue
											error_list.append(
											    f'''The README has several first-level headings: {", ".join(["`"+x+"`" for x in list(self.content.keys()					)]					)}. Only one heading is expected. Skipping further validation for this README.'''					)
							elif num_first_level_keys < 1:
											# If less than one, append error.
											error_list.append(
											    """The README has no first-level headings. One heading is expected. Skipping further validation for this README."""					)

							else:
											# If one exactly
											UpperCamelCase_:							int		=  list(self.content.keys()					)[0]  # Get the key
											if start_key.startswith("""Dataset Card for"""					):  # Check correct start
															# If the starting is correct, validate all the sections
															UpperCamelCase_,      UpperCamelCase_,      UpperCamelCase_:							int		=  self.content[start_key].validate(
															    readme_structure["""subsections"""][0]					)
															error_list += sec_error_list
															warning_list += sec_warning_list
											else:
															# If not found, append error
															error_list.append(
															    """No first-level heading starting with `Dataset Card for` found in README. Skipping further validation for this README."""					)
							if error_list:
											# If there are errors, do not return the dictionary as it is invalid
											return {}, error_list, warning_list
							else:
											return self.to_dict(), error_list, warning_list


if __name__ == "__main__":
							from argparse import ArgumentParser

							lowerCamelCase_  :       List[str]					      =     ArgumentParser(usage="""Validate the content (excluding YAML tags) of a README.md file.""")
							ap.add_argument("""readme_filepath""")
							lowerCamelCase_  :       Tuple					      =     ap.parse_args()
							lowerCamelCase_  :       Union[str, Any]					      =     Path(args.readme_filepath)
							lowerCamelCase_  :       Tuple					      =     ReadMe.from_readme(readme_filepath)








def 				A__    (  lowerCamelCase = 20  )     ->		int:

				try:
								UpperCamelCase_:							int		=  int(lowerCamelCase  )
				except (TypeError, ValueError):
								raise TypeError("""Parameter n must be int or castable to int."""  )
				if n <= 0:
								raise ValueError("""Parameter n must be greater than or equal to one."""  )
				UpperCamelCase_:							Any		=  0
				while 1:
								i += n * (n - 1)
								UpperCamelCase_:							List[Any]		=  0
								for j in range(2   ,			lowerCamelCase  ):
												if i % j != 0:
																UpperCamelCase_:							Union[str, Any]		=  1
																break
								if nfound == 0:
												if i == 0:
																UpperCamelCase_:							List[str]		=  1
												return i
				return None


if __name__ == "__main__":
							print(F"""{solution() = }""")






