""" Logging system for doc_file_processing """

from __future__ import annotations

from sys import stderr
from traceback import print_exc
from typing import Optional, TextIO, Tuple

from progress import Progress


LOGFILE: Optional[TextIO] = None
VERBOSE: bool = False
PROGRESS_DIALOG: Optional[Progress] = None
PROGRESS_CURRENT: Tuple[int, int] = (0, 1)


def set_logfile(f: Optional[TextIO]) -> None:
    global LOGFILE
    LOGFILE = f

def set_verbose(v: bool) -> None:
    global VERBOSE
    VERBOSE = v

def set_progress_enabled(v: bool) -> None:
    """ Enable or disable the progress dialog """
    global PROGRESS_DIALOG
    if v:
        try:
            PROGRESS_DIALOG = Progress("DBDOC Doc File Processing")
        except Exception:
            PROGRESS_DIALOG = None
    else:
        if PROGRESS_DIALOG: PROGRESS_DIALOG.stop()
        PROGRESS_DIALOG = None


def progress_title(title: str, *, compact=False) -> None:
    """ Set the title of the progress dialog, if enabled """
    if PROGRESS_DIALOG:
        PROGRESS_DIALOG.set_status(title, compact=compact)
        PROGRESS_DIALOG.set_detail1("")
        PROGRESS_DIALOG.set_detail2("")

def progress_major(n: int, m: int) -> None:
    """ Set overall progress to N out of M """
    global PROGRESS_CURRENT
    if PROGRESS_DIALOG:
        PROGRESS_CURRENT = (n, m)
        PROGRESS_DIALOG.set_progress(n, m)

def progress_minor(n: int, m: int) -> None:
    """ Set progress towards the next major progress step to N out of M """
    if PROGRESS_DIALOG:
        N, M = PROGRESS_CURRENT
        PROGRESS_DIALOG.set_progress(N * m + n, M * m)

def progress_start() -> None:
    """ Show the progress dialog, if enabled """
    if PROGRESS_DIALOG: PROGRESS_DIALOG.start()

def progress_stop() -> None:
    """ Hide the progress dialog """
    if PROGRESS_DIALOG: PROGRESS_DIALOG.stop()


def errmsg(s: str) -> None:
    """ Log an error. Appears in logfile and on stderr. """
    if LOGFILE: print(s, file=LOGFILE)
    print(s, file=stderr)
    
def errexc() -> None:
    """ Log the current exception. Appears in logfile and on stderr. """
    if LOGFILE:
        print_exc(file=LOGFILE)
        print(file=LOGFILE)
    print_exc(file=stderr)
    print(file=stderr)
    
def statusmsg(s: str, *, progress_major: bool = False, progress_compact: bool = False) -> None:
    """ Set the current status. Appears in logfile, on stdout, and in progress dialog. """
    if LOGFILE: print(s, file=LOGFILE)
    if PROGRESS_DIALOG and progress_major:
        PROGRESS_DIALOG.set_detail1(s, compact=progress_compact)
        PROGRESS_DIALOG.set_detail2("")
    elif PROGRESS_DIALOG:
        PROGRESS_DIALOG.set_detail2(s, compact=progress_compact)
    print(s)
    
def wrnmsg(s: str) -> None:
    """ Log a warning. Appears in logfile and on stdout. """
    if LOGFILE: print(s, file=LOGFILE)
    print(s)
    
def logmsg(s: str) -> None:
    """ Log a detailed message. Appears on stdout only; not in logfile. """
    print(s)
    
def debugmsg(s: str) -> None:
    """ Log a tracing message. Appears on stdout only if VERBOSE is enabled. """
    if VERBOSE:
        print(s)

def contextmsg(s: str) -> None:
    """ Log context information. Appears in logfile only. """
    if LOGFILE: print(s, file=LOGFILE)