from ..io.path import super_open as super_open
from ..print.output_stream import TeeMultiOutput as TeeMultiOutput
from ..typing import CallableAny as CallableAny
from .common import AbstractBothContextManager as AbstractBothContextManager
from typing import Any, IO, TextIO

class LogToFile(AbstractBothContextManager['LogToFile']):
    ''' Context manager to log to a file.

\tThis context manager allows you to temporarily log output to a file while still printing normally.
\tThe file will receive log messages without ANSI color codes.

\tArgs:
\t\tpath (str): Path to the log file
\t\tmode (str): Mode to open the file in (default: "w")
\t\tencoding (str): Encoding to use for the file (default: "utf-8")
\t\ttee_stdout (bool): Whether to redirect stdout to the file (default: True)
\t\ttee_stderr (bool): Whether to redirect stderr to the file (default: True)
\t\tignore_lineup (bool): Whether to ignore lines containing LINE_UP escape sequence in files (default: False)
\t\trestore_on_exit (bool): Whether to restore original stdout/stderr on exit (default: False)
\t\t\tThis ctx uses :py:class:`~stouputils.print.TeeMultiOutput` which handles closed files gracefully, so restoring is not mandatory.

\tExamples:
\t\t.. code-block:: python

\t\t\t> import stouputils as stp
\t\t\t> with stp.LogToFile("output.log"):
\t\t\t>     stp.info("This will be logged to output.log and printed normally")
\t\t\t>     print("This will also be logged")

\t\t\t> with stp.LogToFile("output.log") as log_ctx:
\t\t\t>     stp.warning("This will be logged to output.log and printed normally")
\t\t\t>     log_ctx.change_file("new_file.log")
\t\t\t>     print("This will be logged to new_file.log")
\t'''
    path: str
    mode: str
    encoding: str
    tee_stdout: bool
    tee_stderr: bool
    ignore_lineup: bool
    restore_on_exit: bool
    file: IO[Any]
    original_stdout: TextIO
    original_stderr: TextIO
    def __init__(self, path: str, mode: str = 'w', encoding: str = 'utf-8', tee_stdout: bool = True, tee_stderr: bool = True, ignore_lineup: bool = True, restore_on_exit: bool = False) -> None: ...
    def __enter__(self) -> LogToFile:
        """ Enter context manager which opens the log file and redirects stdout/stderr """
    def __exit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: Any | None) -> None:
        """ Exit context manager which closes the log file and restores stdout/stderr """
    async def __aenter__(self) -> LogToFile:
        """ Enter async context manager which opens the log file and redirects stdout/stderr """
    async def __aexit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: Any | None) -> None:
        """ Exit async context manager which closes the log file and restores stdout/stderr """
    def change_file(self, new_path: str) -> None:
        """ Change the log file to a new path.

\t\tArgs:
\t\t\tnew_path (str): New path to the log file
\t\t"""
    @staticmethod
    def common(logs_folder: str, filepath: str, func: CallableAny, *args: Any, **kwargs: Any) -> Any:
        ''' Common code used at the beginning of a program to launch main function

\t\tArgs:
\t\t\tlogs_folder (str): Folder to store logs in
\t\t\tfilepath    (str): Path to the main function
\t\t\tfunc        (CallableAny): Main function to launch
\t\t\t*args       (tuple[Any, ...]): Arguments to pass to the main function
\t\t\t**kwargs    (dict[str, Any]): Keyword arguments to pass to the main function
\t\tReturns:
\t\t\tAny: Return value of the main function

\t\tExamples:
\t\t\t>>> if __name__ == "__main__":
\t\t\t...     LogToFile.common(f"{ROOT}/logs", __file__, main)
\t\t'''
