from __future__ import annotations

import io
import os
import re
import sys


# types
if False:
    from typing import Protocol, Any
    class Pager(Protocol):
        def __call__(self, text: str, title: str = "") -> None:
            ...


def get_pager() -> Pager:
    """Decide what method to use for paging through text."""
    if not hasattr(sys.stdin, "isatty"):
        return plain_pager
    if not hasattr(sys.stdout, "isatty"):
        return plain_pager
    if not sys.stdin.isatty() or not sys.stdout.isatty():
        return plain_pager
    if sys.platform == "emscripten":
        return plain_pager
    use_pager = os.environ.get('MANPAGER') or os.environ.get('PAGER')
    if use_pager:
        if sys.platform == 'win32': # pipes completely broken in Windows
            return lambda text, title='': tempfile_pager(plain(text), use_pager)
        elif os.environ.get('TERM') in ('dumb', 'emacs'):
            return lambda text, title='': pipe_pager(plain(text), use_pager, title)
        else:
            return lambda text, title='': pipe_pager(text, use_pager, title)
    if os.environ.get('TERM') in ('dumb', 'emacs'):
        return plain_pager
    if sys.platform == 'win32':
        return lambda text, title='': tempfilepager(plain(text), 'more <')
    if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0:
        return lambda text, title='': pipe_pager(text, 'less', title)

    import tempfile
    (fd, filename) = tempfile.mkstemp()
    os.close(fd)
    try:
        if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0:
            return lambda text, title='': pipe_pager(text, 'more', title)
        else:
            return tty_pager
    finally:
        os.unlink(filename)


def escape_stdout(text: str) -> str:
    # Escape non-encodable characters to avoid encoding errors later
    encoding = getattr(sys.stdout, 'encoding', None) or 'utf-8'
    return text.encode(encoding, 'backslashreplace').decode(encoding)


def escape_less(s: str) -> str:
    return re.sub(r'([?:.%\\])', r'\\\1', s)


def plain(text: str) -> str:
    """Remove boldface formatting from text."""
    return re.sub('.\b', '', text)


def tty_pager(text: str, title: str = '') -> None:
    """Page through text on a text terminal."""
    lines = plain(escape_stdout(text)).split('\n')
    has_tty = False
    try:
        import tty
        import termios
        fd = sys.stdin.fileno()
        old = termios.tcgetattr(fd)
        tty.setcbreak(fd)
        getchar = lambda: sys.stdin.read(1)
        has_tty = True
    except (ImportError, AttributeError, io.UnsupportedOperation):
        getchar = lambda: sys.stdin.readline()[:-1][:1]

    try:
        try:
            h = int(os.environ.get('LINES', 0))
        except ValueError:
            h = 0
        if h <= 1:
            h = 25
        r = inc = h - 1
        sys.stdout.write('\n'.join(lines[:inc]) + '\n')
        while lines[r:]:
            sys.stdout.write('-- more --')
            sys.stdout.flush()
            c = getchar()

            if c in ('q', 'Q'):
                sys.stdout.write('\r          \r')
                break
            elif c in ('\r', '\n'):
                sys.stdout.write('\r          \r' + lines[r] + '\n')
                r = r + 1
                continue
            if c in ('b', 'B', '\x1b'):
                r = r - inc - inc
                if r < 0: r = 0
            sys.stdout.write('\n' + '\n'.join(lines[r:r+inc]) + '\n')
            r = r + inc

    finally:
        if has_tty:
            termios.tcsetattr(fd, termios.TCSAFLUSH, old)


def plain_pager(text: str, title: str = '') -> None:
    """Simply print unformatted text.  This is the ultimate fallback."""
    sys.stdout.write(plain(escape_stdout(text)))


def pipe_pager(text: str, cmd: str, title: str = '') -> None:
    """Page through text by feeding it to another program."""
    import subprocess
    env = os.environ.copy()
    if title:
        title += ' '
    esc_title = escape_less(title)
    prompt_string = (
        f' {esc_title}' +
        '?ltline %lt?L/%L.'
        ':byte %bB?s/%s.'
        '.'
        '?e (END):?pB %pB\\%..'
        ' (press h for help or q to quit)')
    env['LESS'] = '-RmPm{0}$PM{0}$'.format(prompt_string)
    proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
                            errors='backslashreplace', env=env)
    assert proc.stdin is not None
    try:
        with proc.stdin as pipe:
            try:
                pipe.write(text)
            except KeyboardInterrupt:
                # We've hereby abandoned whatever text hasn't been written,
                # but the pager is still in control of the terminal.
                pass
    except OSError:
        pass # Ignore broken pipes caused by quitting the pager program.
    while True:
        try:
            proc.wait()
            break
        except KeyboardInterrupt:
            # Ignore ctl-c like the pager itself does.  Otherwise the pager is
            # left running and the terminal is in raw mode and unusable.
            pass


def tempfile_pager(text: str, cmd: str, title: str = '') -> None:
    """Page through text by invoking a program on a temporary file."""
    import tempfile
    with tempfile.TemporaryDirectory() as tempdir:
        filename = os.path.join(tempdir, 'pydoc.out')
        with open(filename, 'w', errors='backslashreplace',
                  encoding=os.device_encoding(0) if
                  sys.platform == 'win32' else None
                  ) as file:
            file.write(text)
        os.system(cmd + ' "' + filename + '"')
