# Path: approvaltests/reporters/generic_diff_reporter_factory.py
# class GenericDiffReporterFactory(object):
#     reporters: List[GenericDiffReporterConfig] = []
# 
#     def __init__(self) -> None:
#         self.load(get_adjacent_file("reporters.json"))
# 
#     def add_default_reporter_config(self, config):
#         self.reporters.insert(0, create_config(config))
# 
#     def list(self) -> List[str]:
#         return [r.name for r in self.reporters]
# 
#     def get(self, reporter_name: str) -> Reporter:
#         reporter = GenericDiffReporterFactory.get_reporter_programmmatically(
#             reporter_name
#         )
#         return reporter or self.get_from_json_config(reporter_name)
# 
#     @staticmethod
#     def get_reporter_programmmatically(reporter_name: str) -> Optional[Reporter]:
#         reporters = {"BeyondCompare": ReportWithBeyondCompare,
#                      "WinMerge": ReportWithWinMerge}
#         clazz = reporters.get(reporter_name)
#         return clazz and clazz()
# 
#     def get_from_json_config(self, reporter_name: str) -> Reporter:
#         config = next((r for r in self.reporters if r.name == reporter_name), None)
#         if not config:
#             return NoConfigReporter()
#         return self._create_reporter(config)
# 
#     @staticmethod
#     def _create_reporter(config: GenericDiffReporterConfig) -> GenericDiffReporter:
#         return GenericDiffReporter(config)
# 
#     def save(self, file_name: str) -> str:
#         with open(file_name, "w") as f:
#             json.dump(
#                 [reporter.serialize() for reporter in self.reporters],
#                 f,
#                 sort_keys=True,
#                 indent=2,
#                 separators=(",", ": "),
#             )
#         return file_name
# 
#     def load(self, file_name: str) -> List[GenericDiffReporterConfig]:
#         with open(file_name, "r") as f:
#             configs = json.load(f)
#         self.reporters = [create_config(config) for config in configs]
#         return self.reporters
# 
#     def get_first_working(self) -> Optional[GenericDiffReporter]:
#         working = (i for i in self.get_all_reporters() if i.is_working())
#         return next(working, None)
# 
#     def get_all_reporters(self) -> Iterator[GenericDiffReporter]:
#         instances = (self._create_reporter(r) for r in self.reporters)
#         return instances
# 
#     def remove(self, reporter_name: str) -> None:
#         self.reporters = [r for r in self.reporters if r.name != reporter_name]
# 
# Path: approvaltests/reporters/first_working_reporter.py
# class FirstWorkingReporter(Reporter):
#     """
#     A composite reporter that goes through a list
#     of reporters, running the first one that is
#     working on the current machine.
# 
#     This is mostly an implementation detail of other
#     classes in the library, but it may be useful in scenarios
#     where a team wants to supply a list of custom reporter,
#     and have the first working one of these be used.
# 
#     See also MultiReporter.
#     """
# 
#     def __init__(self, *reporters) -> None:
#         self.reporters = reporters
# 
#     def report(self, received_path: str, approved_path: str) -> bool:
#         for r in self.reporters:
#             try:
#                 success = r.report(received_path, approved_path)
#                 if success:
#                     return True
#             except:
#                 pass
# 
#         return False
# 
#     def __str__(self):
#         reporters = ", ".join(str(s) for s in self.reporters)
#         return f"FirstWorkingReporter({reporters})"
# 
#     __repr__ = __str__
# 
#     def __eq__(self, other) -> bool:
#         return repr(self) == repr(other)
# 
# Path: approvaltests/reporters/introduction_reporter.py
# class IntroductionReporter(Reporter):
# 
#     def report(self, received_path: str, approved_path: str) -> bool:
#         print(self.get_text())
#         return PythonNativeReporter().report(received_path, approved_path)
# 
#     def get_text(self):
#         return '''
#         Welcome to ApprovalTests!
#         No DiffReporters have been detected on this system.
#         To learn more, visit [Introduction to Reporters](https://github.com/approvals/ApprovalTests.Python/blob/main/docs/tutorial/intro-to-reporters.md)
#         '''
#     def __str__(self):
#         return self.__class__.__name__
# 
#     __repr__ = __str__
# 
# Path: approvaltests/reporters/python_native_reporter.py
# class PythonNativeReporter(Reporter):
#     """
#     A reporter that outputs diff straight
#     to standard output.
# 
#     This is useful when running in a non-GUI environment,
#     such as in Continuous Integration systems.
#     """
# 
#     def report(self, received_path: str, approved_path: str) -> bool:
#         ensure_file_exists(approved_path)
#         print(calculate_diff_with_approve_instruction(received_path, approved_path))
#         return True
# 
#     def __str__(self):
#         return self.__class__.__name__
# 
#     __repr__ = __str__


from approvaltests.reporters.generic_diff_reporter_factory import (
    GenericDiffReporterFactory,
)
from .first_working_reporter import FirstWorkingReporter
from .introduction_reporter import IntroductionReporter
from .python_native_reporter import PythonNativeReporter


class DiffReporter(FirstWorkingReporter):
    """
    The DiffReporter class goes through a chain of possible diffing tools,
    to find the first option installed on your system.

    If none are found, it falls back to writing the diffs on
    the console.

    At present, the default Reporter is the DiffReporter.
    """

    def __init__(self, reporter_factory=None):

# Path: approvaltests/reporters/generic_diff_reporter_factory.py
# class GenericDiffReporterFactory(object):
#     reporters: List[GenericDiffReporterConfig] = []
# 
#     def __init__(self) -> None:
#         self.load(get_adjacent_file("reporters.json"))
# 
#     def add_default_reporter_config(self, config):
#         self.reporters.insert(0, create_config(config))
# 
#     def list(self) -> List[str]:
#         return [r.name for r in self.reporters]
# 
#     def get(self, reporter_name: str) -> Reporter:
#         reporter = GenericDiffReporterFactory.get_reporter_programmmatically(
#             reporter_name
#         )
#         return reporter or self.get_from_json_config(reporter_name)
# 
#     @staticmethod
#     def get_reporter_programmmatically(reporter_name: str) -> Optional[Reporter]:
#         reporters = {"BeyondCompare": ReportWithBeyondCompare,
#                      "WinMerge": ReportWithWinMerge}
#         clazz = reporters.get(reporter_name)
#         return clazz and clazz()
# 
#     def get_from_json_config(self, reporter_name: str) -> Reporter:
#         config = next((r for r in self.reporters if r.name == reporter_name), None)
#         if not config:
#             return NoConfigReporter()
#         return self._create_reporter(config)
# 
#     @staticmethod
#     def _create_reporter(config: GenericDiffReporterConfig) -> GenericDiffReporter:
#         return GenericDiffReporter(config)
# 
#     def save(self, file_name: str) -> str:
#         with open(file_name, "w") as f:
#             json.dump(
#                 [reporter.serialize() for reporter in self.reporters],
#                 f,
#                 sort_keys=True,
#                 indent=2,
#                 separators=(",", ": "),
#             )
#         return file_name
# 
#     def load(self, file_name: str) -> List[GenericDiffReporterConfig]:
#         with open(file_name, "r") as f:
#             configs = json.load(f)
#         self.reporters = [create_config(config) for config in configs]
#         return self.reporters
# 
#     def get_first_working(self) -> Optional[GenericDiffReporter]:
#         working = (i for i in self.get_all_reporters() if i.is_working())
#         return next(working, None)
# 
#     def get_all_reporters(self) -> Iterator[GenericDiffReporter]:
#         instances = (self._create_reporter(r) for r in self.reporters)
#         return instances
# 
#     def remove(self, reporter_name: str) -> None:
#         self.reporters = [r for r in self.reporters if r.name != reporter_name]
# 
# Path: approvaltests/reporters/first_working_reporter.py
# class FirstWorkingReporter(Reporter):
#     """
#     A composite reporter that goes through a list
#     of reporters, running the first one that is
#     working on the current machine.
# 
#     This is mostly an implementation detail of other
#     classes in the library, but it may be useful in scenarios
#     where a team wants to supply a list of custom reporter,
#     and have the first working one of these be used.
# 
#     See also MultiReporter.
#     """
# 
#     def __init__(self, *reporters) -> None:
#         self.reporters = reporters
# 
#     def report(self, received_path: str, approved_path: str) -> bool:
#         for r in self.reporters:
#             try:
#                 success = r.report(received_path, approved_path)
#                 if success:
#                     return True
#             except:
#                 pass
# 
#         return False
# 
#     def __str__(self):
#         reporters = ", ".join(str(s) for s in self.reporters)
#         return f"FirstWorkingReporter({reporters})"
# 
#     __repr__ = __str__
# 
#     def __eq__(self, other) -> bool:
#         return repr(self) == repr(other)
# 
# Path: approvaltests/reporters/introduction_reporter.py
# class IntroductionReporter(Reporter):
# 
#     def report(self, received_path: str, approved_path: str) -> bool:
#         print(self.get_text())
#         return PythonNativeReporter().report(received_path, approved_path)
# 
#     def get_text(self):
#         return '''
#         Welcome to ApprovalTests!
#         No DiffReporters have been detected on this system.
#         To learn more, visit [Introduction to Reporters](https://github.com/approvals/ApprovalTests.Python/blob/main/docs/tutorial/intro-to-reporters.md)
#         '''
#     def __str__(self):
#         return self.__class__.__name__
# 
#     __repr__ = __str__
# 
# Path: approvaltests/reporters/python_native_reporter.py
# class PythonNativeReporter(Reporter):
#     """
#     A reporter that outputs diff straight
#     to standard output.
# 
#     This is useful when running in a non-GUI environment,
#     such as in Continuous Integration systems.
#     """
# 
#     def report(self, received_path: str, approved_path: str) -> bool:
#         ensure_file_exists(approved_path)
#         print(calculate_diff_with_approve_instruction(received_path, approved_path))
#         return True
# 
#     def __str__(self):
#         return self.__class__.__name__
# 
#     __repr__ = __str__


# Path: approvaltests/reporters/diff_reporter.py
from approvaltests.reporters.generic_diff_reporter_factory import (
    GenericDiffReporterFactory,
)
from .first_working_reporter import FirstWorkingReporter
from .introduction_reporter import IntroductionReporter
from .python_native_reporter import PythonNativeReporter



class DiffReporter(FirstWorkingReporter):
    """
    The DiffReporter class goes through a chain of possible diffing tools,
    to find the first option installed on your system.

    If none are found, it falls back to writing the diffs on
    the console.

    At present, the default Reporter is the DiffReporter.
    """

    def __init__(self, reporter_factory=None):

        factory = reporter_factory or GenericDiffReporterFactory()