#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see
# https://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
"""
Copyright (C) 2010-2011  Lucas De Marchi <lucas.de.marchi@gmail.com>
Copyright (C) 2011  ProFUSION embedded systems
"""

import argparse
import configparser
import ctypes
import fnmatch
import itertools
import os
import re
import shlex
import stat
import sys
import tempfile
import textwrap
from collections.abc import Iterable, Sequence
from re import Match, Pattern
from typing import (
    Any,
    Optional,
    TextIO,
)

if sys.platform == "win32":
    from ctypes import wintypes

    ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
    STD_OUTPUT_HANDLE = wintypes.HANDLE(-11)

from ._spellchecker import Misspelling, build_dict
from ._text_util import fix_case

# autogenerated by setuptools_scm
from ._version import (  # type: ignore[import-not-found]
    __version__ as VERSION,  # noqa: N812
)

word_regex_def = r"[\w\-'’]+"  # noqa: RUF001
# While we want to treat characters like ( or " as okay for a starting break,
# these may occur unescaped in URIs, and so we are more restrictive on the
# endpoint.  Emails are more restrictive, so the endpoint remains flexible.
uri_regex_def = (
    r"(\b(?:https?|[ts]?ftp|file|git|smb)://[^\s]+(?=$|\s)|\b[\w.%+-]+@[\w.-]+\b)"
)
codespell_ignore_tag = "codespell:ignore"
codespell_ignore_next_line_tag = "codespell:ignore-next-line"
inline_ignore_regex = re.compile(
    rf"[^\w\s]\s*{codespell_ignore_tag}(?!-)\b(\s+(?P<words>[\w,]*))?"
)
ignore_next_line_regex = re.compile(
    rf"[^\w\s]\s*{codespell_ignore_next_line_tag}\b(\s+(?P<words>[\w,]*))?"
)
# Editorial "[sic]" marker following a word, allowing an intervening closing
# quote so a quoted misspelling like `"..." [sic]` is matched.
sic_regex = re.compile(r"[\"'’”)\s]*\[sic\]", re.IGNORECASE)  # noqa: RUF001
USAGE = """
\t%prog [OPTIONS] [file1 file2 ... fileN]
"""

supported_languages_en = ("en", "en_GB", "en_US", "en_CA", "en_AU")
supported_languages = supported_languages_en

# Users might want to link this file into /usr/local/bin, so we resolve the
# symbolic link path to the real path if necessary.
_data_root = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data")
_builtin_dictionaries = (
    # name, desc, name, err in aspell, correction in aspell, \
    # err dictionary array, rep dictionary array
    # The arrays must contain the names of aspell dictionaries
    # The aspell tests here aren't the ideal state, but the None's are
    # realistic for obscure words
    ("clear", "for unambiguous errors", "", False, None, supported_languages_en, None),
    (
        "rare",
        "for rare (but valid) words that are likely to be errors",
        "_rare",
        None,
        None,
        None,
        None,
    ),
    (
        "informal",
        "for making informal words more formal",
        "_informal",
        True,
        True,
        supported_languages_en,
        supported_languages_en,
    ),
    (
        "usage",
        "for replacing phrasing with recommended terms",
        "_usage",
        None,
        None,
        None,
        None,
    ),
    (
        "code",
        "for words from code and/or mathematics that are likely to be typos in other contexts (such as uint)",  # noqa: E501
        "_code",
        None,
        None,
        None,
        None,
    ),
    (
        "names",
        "for valid proper names that might be typos",
        "_names",
        None,
        None,
        None,
        None,
    ),
    (
        "en-GB_to_en-US",
        "for corrections from en-GB to en-US",
        "_en-GB_to_en-US",
        True,
        True,
        ("en_GB",),
        ("en_US",),
    ),
    (
        "en_to_en-OX",
        "for corrections from en to en-OX",
        "_en_to_en-OX_AUTOGENERATED",
        None,
        None,
        None,
        None,
    ),
)
_builtin_default = "clear,rare"

# docs say os.EX_USAGE et al. are only available on Unix systems, so to be safe
# we protect and just use the values they are on macOS and Linux
EX_OK = 0
EX_USAGE = 64
EX_DATAERR = 65
EX_CONFIG = 78

# OPTIONS:
#
# ARGUMENTS:
#    dict_filename       The file containing the dictionary of misspellings.
#                        If set to '-', it will be read from stdin
#    file1 .. fileN      Files to check spelling


class QuietLevels:
    NONE = 0
    ENCODING = 1
    BINARY_FILE = 2
    DISABLED_FIXES = 4
    NON_AUTOMATIC_FIXES = 8
    FIXES = 16
    CONFIG_FILES = 32


class GlobMatch:
    def __init__(self, pattern: list[str]) -> None:
        self.pattern_list: list[str] = pattern

    def match(self, filename: str) -> bool:
        return any(fnmatch.fnmatch(filename, p) for p in self.pattern_list)


class TermColors:
    def __init__(self) -> None:
        self.FILE = "\033[33m"
        self.WWORD = "\033[31m"
        self.FWORD = "\033[32m"
        self.DISABLE = "\033[0m"

    def disable(self) -> None:
        self.FILE = ""
        self.WWORD = ""
        self.FWORD = ""
        self.DISABLE = ""


class Summary:
    def __init__(self) -> None:
        self.summary: dict[str, int] = {}

    def update(self, wrongword: str) -> None:
        if wrongword in self.summary:
            self.summary[wrongword] += 1
        else:
            self.summary[wrongword] = 1

    def __str__(self) -> str:
        keys = list(self.summary.keys())
        keys.sort()

        return "\n".join(
            [f"{key}{self.summary.get(key):{15 - len(key)}}" for key in keys]
        )


class FileOpener:
    def __init__(
        self,
        use_chardet: bool,
        quiet_level: int,
        ignore_multiline_regex: Optional[Pattern[str]],
    ) -> None:
        self.use_chardet = use_chardet
        if use_chardet:
            self.init_chardet()
        self.quiet_level = quiet_level
        self.ignore_multiline_regex = ignore_multiline_regex

    def init_chardet(self) -> None:
        try:
            import chardet  # noqa: F401
        except ImportError:
            msg = (
                "There's no chardet installed to import from. "
                "Please, install it and check your PYTHONPATH "
                "environment variable"
            )
            raise ImportError(msg)
        try:
            from chardet import UniversalDetector
        except ImportError:  # chardet < 7
            from chardet.universaldetector import UniversalDetector

        self.encdetector = UniversalDetector()

    def open(self, filename: str) -> tuple[list[tuple[bool, int, list[str]]], str]:
        if self.use_chardet:
            return self.open_with_chardet(filename)
        return self.open_with_internal(filename)

    def open_with_chardet(
        self, filename: str
    ) -> tuple[list[tuple[bool, int, list[str]]], str]:
        self.encdetector.reset()
        with open(filename, "rb") as fb:
            for line in fb:
                self.encdetector.feed(line)
                if self.encdetector.done:
                    break
        self.encdetector.close()
        encoding = self.encdetector.result["encoding"]

        try:
            f = open(filename, encoding=encoding, newline="")
        except UnicodeDecodeError:
            print(f"ERROR: Could not detect encoding: {filename}", file=sys.stderr)
            raise
        except LookupError:
            print(
                f"ERROR: Don't know how to handle encoding {encoding}: {filename}",
                file=sys.stderr,
            )
            raise
        else:
            lines = self.get_lines(f)
            f.close()

        return lines, f.encoding

    def open_with_internal(
        self, filename: str
    ) -> tuple[list[tuple[bool, int, list[str]]], str]:
        encoding = None
        first_try = True
        for encoding in ("utf-8", "iso-8859-1"):
            if first_try:
                first_try = False
            elif not self.quiet_level & QuietLevels.ENCODING:
                print(f'WARNING: Trying next encoding "{encoding}"', file=sys.stderr)
            with open(filename, encoding=encoding, newline="") as f:
                try:
                    lines = self.get_lines(f)
                except UnicodeDecodeError:
                    if not self.quiet_level & QuietLevels.ENCODING:
                        print(
                            f'WARNING: Cannot decode file using encoding "{encoding}": '
                            f"{filename}",
                            file=sys.stderr,
                        )
                else:
                    break
        else:
            # reading with encoding "iso-8859-1" cannot fail with UnicodeDecodeError
            msg = "Unknown encoding"
            raise RuntimeError(msg)  # pragma: no cover

        return lines, encoding

    def get_lines(self, f: TextIO) -> list[tuple[bool, int, list[str]]]:
        fragments = []
        line_number = 0
        if self.ignore_multiline_regex:
            text = f.read()
            pos = 0
            for m in re.finditer(self.ignore_multiline_regex, text):
                lines = text[pos : m.start()].splitlines(True)
                fragments.append((False, line_number, lines))
                line_number += len(lines)
                lines = m.group().splitlines(True)
                fragments.append((True, line_number, lines))
                line_number += len(lines) - 1
                pos = m.end()
            lines = text[pos:].splitlines(True)
            fragments.append((False, line_number, lines))
        else:
            fragments.append((False, line_number, f.readlines()))
        return fragments


# -.-:-.-:-.-:-.:-.-:-.-:-.-:-.-:-.:-.-:-.-:-.-:-.-:-.:-.-:-


# If someday this breaks, we can just switch to using RawTextHelpFormatter,
# but it has the disadvantage of not wrapping our long lines.


class NewlineHelpFormatter(argparse.HelpFormatter):
    """Help formatter that preserves newlines and deals with lists."""

    def _split_lines(self, text: str, width: int) -> list[str]:
        parts = text.split("\n")
        out = []
        for part in parts:
            # Eventually we could allow others...
            indent_start = "- "
            offset = len(indent_start) if part.startswith(indent_start) else 0
            part = part[offset:]
            part = self._whitespace_matcher.sub(" ", part).strip()
            parts = textwrap.wrap(part, width - offset)
            parts = [" " * offset + p for p in parts]
            if offset:
                parts[0] = indent_start + parts[0][offset:]
            out.extend(parts)
        return out


def _toml_to_parseconfig(toml_dict: dict[str, Any]) -> dict[str, Any]:
    """Convert a dict read from a TOML file to the parseconfig.read_dict() format."""
    return {
        k: "" if v is True else ",".join(v) if isinstance(v, list) else v
        for k, v in toml_dict.items()
        if v is not False
    }


def _supports_ansi_colors() -> bool:
    if sys.platform == "win32":
        # Windows Terminal enables ANSI escape codes by default. In other cases
        # it is disabled.
        # See https://ss64.com/nt/syntax-ansi.html for more information.
        kernel32 = ctypes.WinDLL("kernel32")

        # fmt: off
        kernel32.GetConsoleMode.argtypes = (
            wintypes.HANDLE,   # _In_  hConsoleHandle
            wintypes.LPDWORD,  # _Out_ lpMode
        )
        # fmt: on
        kernel32.GetConsoleMode.restype = wintypes.BOOL

        mode = wintypes.DWORD()
        handle = kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
        if not kernel32.GetConsoleMode(handle, ctypes.byref(mode)):
            # TODO: print a warning with the error message on stderr?
            return False

        return (mode.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0
    elif sys.platform == "wasi":
        # WASI disables ANSI escape codes for security reasons.
        # See https://github.com/WebAssembly/WASI/issues/162.
        return False
    elif sys.stdout.isatty():
        return True

    return False


def parse_options(
    args: Sequence[str],
) -> tuple[argparse.Namespace, argparse.ArgumentParser, list[str]]:
    # Split lines read from `@PATH` using shlex.split(), otherwise default
    # behaviour is to have one arg per line. See:
    # https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.convert_arg_line_to_args
    class ArgumentParser2(argparse.ArgumentParser):
        def convert_arg_line_to_args(self, arg_line: str) -> list[str]:
            if sys.platform == "win32":
                # On Windows, shlex.split() seems to be messed up by back
                # slashes. Temporarily changing them to forward slashes seems
                # to make things work better.
                arg_line = arg_line.replace("\\", "/")
                ret = shlex.split(arg_line)
                ret = [p.replace("/", "\\") for p in ret]
            else:
                ret = shlex.split(arg_line)
            return ret

    parser = ArgumentParser2(
        formatter_class=NewlineHelpFormatter,
        fromfile_prefix_chars="@",
        epilog="Use @PATH to read additional arguments from file PATH.",
    )

    parser.set_defaults(colors=_supports_ansi_colors())
    parser.add_argument("--version", action="version", version=VERSION)

    parser.add_argument(
        "-d",
        "--disable-colors",
        action="store_false",
        dest="colors",
        help="disable colors, even when printing to terminal",
    )
    parser.add_argument(
        "-c",
        "--enable-colors",
        action="store_true",
        dest="colors",
        help="enable colors, even when not printing to terminal",
    )

    parser.add_argument(
        "-w",
        "--write-changes",
        action="store_true",
        default=False,
        help="write changes in place if possible",
    )

    parser.add_argument(
        "-D",
        "--dictionary",
        action="append",
        help="comma-separated list of custom dictionary files that "
        "contain spelling corrections. If this flag is not specified "
        'or equals "-" then the default dictionary is used.',
    )
    builtin_opts = "\n- ".join(
        [""] + [f"{d[0]!r} {d[1]}" for d in _builtin_dictionaries]
    )
    parser.add_argument(
        "--builtin",
        dest="builtin",
        default=_builtin_default,
        metavar="BUILTIN-LIST",
        help="comma-separated list of builtin dictionaries "
        'to include (when "-D -" or no "-D" is passed). '
        "Use 'all' to include every builtin dictionary. "
        "Current options are:" + builtin_opts + "\n"
        "The default is %(default)r.",
    )
    parser.add_argument(
        "--ignore-regex",
        action="store",
        type=str,
        help="regular expression that is used to find "
        "patterns to ignore by treating as whitespace. "
        "When writing regular expressions, consider "
        "ensuring there are boundary non-word chars, "
        'e.g., "\\bmatch\\b". Defaults to '
        "empty/disabled.",
    )
    parser.add_argument(
        "--ignore-multiline-regex",
        action="store",
        type=str,
        help="regular expression that is used to ignore "
        "text that may span multi-line regions. "
        "The regex is run with re.DOTALL. For example to "
        "allow skipping of regions of Python code using "
        "begin/end comments one could use: "
        "--ignore-multiline-regex "
        "'# codespell:ignore-begin *\\n.*# codespell:ignore-end *\\n'. "
        "Defaults to empty/disabled.",
    )
    parser.add_argument(
        "-I",
        "--ignore-words",
        action="append",
        metavar="FILES",
        help="comma-separated list of files that contain "
        "words to be ignored by codespell. Files must contain "
        "1 word per line. Words are case sensitive based on "
        "how they are written in the dictionary file.",
    )
    parser.add_argument(
        "-L",
        "--ignore-words-list",
        action="append",
        metavar="WORDS",
        help="comma-separated list of words to be ignored "
        "by codespell. Words are case sensitive based on "
        "how they are written in the dictionary file.",
    )
    parser.add_argument(
        "--uri-ignore-words-list",
        action="append",
        metavar="WORDS",
        help="comma-separated list of words to be ignored "
        "by codespell in URIs and emails only. Words are "
        "case sensitive based on how they are written in "
        'the dictionary file. If set to "*", all '
        "misspelling in URIs and emails will be ignored.",
    )
    parser.add_argument(
        "-r",
        "--regex",
        action="store",
        type=str,
        help="regular expression that is used to find words. "
        "By default any alphanumeric character, the "
        "underscore, the hyphen, and the apostrophe are "
        "used to build words. This option cannot be "
        "specified together with --write-changes.",
    )
    parser.add_argument(
        "--uri-regex",
        action="store",
        type=str,
        help="regular expression that is used to find URIs "
        "and emails. A default expression is provided.",
    )
    parser.add_argument(
        "-s",
        "--summary",
        action="store_true",
        default=False,
        help="print summary of fixes",
    )

    parser.add_argument(
        "--count",
        action="store_true",
        default=False,
        help="print the number of errors as the last line of stderr",
    )

    parser.add_argument(
        "-S",
        "--skip",
        action="append",
        help="comma-separated list of files to skip. It "
        "accepts globs as well. E.g.: if you want "
        "codespell to skip .eps and .txt files, "
        'you\'d give "*.eps,*.txt" to this option.',
    )

    parser.add_argument(
        "-x",
        "--exclude-file",
        action="append",
        type=str,
        metavar="FILES",
        help="ignore whole lines that match those in "
        "the comma-separated list of files EXCLUDE. "
        "The lines in these files should match the "
        "to-be-excluded lines exactly",
    )

    parser.add_argument(
        "-i",
        "--interactive",
        action="store",
        type=int,
        default=0,
        choices=range(0, 4),
        help="set interactive mode when writing changes:\n"
        "- 0: no interactivity.\n"
        "- 1: ask for confirmation; 'a'/'s' answer for the rest of the file.\n"
        "- 2: ask user to choose one fix when more than one is available;"
        " 'Na'/'s' answer for the rest of the file.\n"
        "- 3: both 1 and 2",
        metavar="MODE",
    )

    parser.add_argument(
        "-q",
        "--quiet-level",
        action="store",
        type=int,
        default=34,
        choices=range(0, 64),
        help="bitmask that allows suppressing messages:\n"
        "- 0: print all messages.\n"
        "- 1: disable warnings about wrong encoding.\n"
        "- 2: disable warnings about binary files.\n"
        "- 4: omit warnings about automatic fixes that were disabled in the dictionary.\n"  # noqa: E501
        "- 8: don't print anything for non-automatic fixes.\n"
        "- 16: don't print the list of fixed files.\n"
        "- 32: don't print configuration files.\n"
        "As usual with bitmasks, these levels can be "
        "combined; e.g. use 3 for levels 1+2, 7 for "
        "1+2+4, 23 for 1+2+4+16, etc. "
        "The default mask is %(default)s.",
        metavar="LEVEL",
    )

    parser.add_argument(
        "-e",
        "--hard-encoding-detection",
        action="store_true",
        default=False,
        help="use chardet to detect the encoding of each "
        "file. This can slow down codespell, but is more "
        "reliable in detecting encodings other than "
        "utf-8, iso8859-1, and ascii.",
    )

    parser.add_argument(
        "-f",
        "--check-filenames",
        action="store_true",
        default=False,
        help="check file names as well",
    )

    parser.add_argument(
        "-H",
        "--check-hidden",
        action="store_true",
        default=False,
        help='check hidden files and directories (those starting with ".") as well.',
    )
    parser.add_argument(
        "-A",
        "--after-context",
        type=int,
        metavar="LINES",
        help="print LINES of trailing context",
    )
    parser.add_argument(
        "-B",
        "--before-context",
        type=int,
        metavar="LINES",
        help="print LINES of leading context",
    )
    parser.add_argument(
        "-C",
        "--context",
        type=int,
        metavar="LINES",
        help="print LINES of surrounding context",
    )
    parser.add_argument(
        "--ignore-sic",
        action="store_true",
        default=False,
        help='ignore a misspelling immediately followed by the editorial "[sic]" '
        "marker (optionally preceded by a closing quote).",
    )
    parser.add_argument(
        "--stdin-single-line",
        action="store_true",
        help="output just a single line for each misspelling in stdin mode",
    )
    parser.add_argument("--config", type=str, help="path to config file.")
    parser.add_argument("--toml", type=str, help="path to a pyproject.toml file.")
    parser.add_argument("files", nargs="*", help="files or directories to check")

    # Parse command line options.
    options = parser.parse_args(list(args))

    # Load config files and look for ``codespell`` options.
    cfg_files = ["setup.cfg", ".codespellrc"]
    if options.config:
        cfg_files.append(options.config)
    config = configparser.ConfigParser(interpolation=None)

    # Read toml before other config files.
    toml_files = []
    used_toml_files = []
    tomllib_raise_error = False
    if os.path.isfile("pyproject.toml"):
        toml_files.append("pyproject.toml")
    if options.toml:
        toml_files.append(options.toml)
        tomllib_raise_error = True
    if toml_files:
        if sys.version_info >= (3, 11):
            import tomllib
        else:
            try:
                import tomli as tomllib  # type: ignore[no-redef]
            except ImportError as e:
                if tomllib_raise_error:
                    msg = (
                        f"tomllib or tomli are required to read pyproject.toml "
                        f"but could not be imported, got: {e}"
                    )
                    raise ImportError(msg) from None
                tomllib = None  # type: ignore[assignment]
        if tomllib is not None:
            for toml_file in toml_files:
                with open(toml_file, "rb") as f:
                    data = tomllib.load(f).get("tool", {}).get("codespell")
                if data is not None:
                    if not isinstance(data, dict):
                        msg = f"{toml_file}: [tool.codespell] must be a table"
                        raise configparser.Error(msg)
                    config.read_dict({"codespell": _toml_to_parseconfig(data)})
                    if toml_file not in used_toml_files:
                        used_toml_files.append(toml_file)

    # Collect which config files are going to be used
    used_ini_files = []
    for cfg_file in cfg_files:
        _cfg = configparser.ConfigParser()
        _cfg.read(cfg_file)
        if _cfg.has_section("codespell"):
            used_ini_files.append(cfg_file)

    # Use INI config files (TOML was already applied above)
    config.read(used_ini_files)
    used_cfg_files = used_toml_files + used_ini_files
    if config.has_section("codespell"):
        # Build a "fake" argv list using option name and value.
        cfg_args = []
        for key in config["codespell"]:
            # Add option as arg.
            cfg_args.append(f"--{key}")
            # If value is blank, skip.
            val = config["codespell"][key]
            if val:
                cfg_args.append(val)

        # Parse config file options.
        options = parser.parse_args(cfg_args)

        # Re-parse command line options to override config.
        options = parser.parse_args(list(args), namespace=options)

    if not options.files:
        options.files.append(".")

    return options, parser, used_cfg_files


def process_ignore_words(
    words: Iterable[str], ignore_words: set[str], ignore_words_cased: set[str]
) -> None:
    for word in words:
        word = word.strip()
        if word == word.lower():
            ignore_words.add(word)
        else:
            ignore_words_cased.add(word)


def parse_ignore_words_option(
    ignore_words_option: list[str],
) -> tuple[set[str], set[str]]:
    ignore_words: set[str] = set()
    ignore_words_cased: set[str] = set()
    if ignore_words_option:
        for comma_separated_words in ignore_words_option:
            process_ignore_words(
                (word.strip() for word in comma_separated_words.split(",")),
                ignore_words,
                ignore_words_cased,
            )
    return (ignore_words, ignore_words_cased)


def build_exclude_hashes(filename: str, exclude_lines: set[str]) -> None:
    with open(filename, encoding="utf-8") as f:
        exclude_lines.update(line.rstrip() for line in f)


def build_ignore_words(
    filename: str, ignore_words: set[str], ignore_words_cased: set[str]
) -> None:
    with open(filename, encoding="utf-8") as f:
        process_ignore_words(
            (line.strip() for line in f), ignore_words, ignore_words_cased
        )


def is_hidden(filename: str, check_hidden: bool) -> bool:
    bfilename = os.path.basename(filename)

    return bfilename not in ("", ".", "..") and (
        not check_hidden and bfilename[0] == "."
    )


def is_text_file(filename: str) -> bool:
    with open(filename, mode="rb") as f:
        s = f.read(1024)
    return b"\x00" not in s


def _no_more_input(misspelling: Misspelling) -> tuple[bool, str, bool]:
    # An unanswered prompt must not count as a "yes": stdin being at EOF means
    # the answers ran out (or never existed), so leave the word alone and stop
    # asking about it in this file.
    print("\nNo answer: leaving the rest of this file alone")
    return False, misspelling.data, True


def ask_for_word_fix(
    line: str,
    match: Match[str],
    misspelling: Misspelling,
    interactivity: int,
    colors: TermColors,
    filename: str,
    lineno: int,
) -> tuple[bool, str, bool]:
    """Ask about one match.

    Returns (fix, data, remember), where data is the replacement in dictionary
    form, uncased, for the caller to case per match, and remember says whether
    the answer was given for the rest of the file rather than for this match.

    This function must not mutate `misspelling`: the object is shared by every
    match of the word in the run, so an answer would leak into every later
    match and file (GH-62).
    """
    cfilename = f"{colors.FILE}{filename}{colors.DISABLE}"
    cline = f"{colors.FILE}{lineno}{colors.DISABLE}"

    wrongword = match.group()
    line_ui = (
        f"{line[: match.start()]}"
        f"{colors.WWORD}{wrongword}{colors.DISABLE}"
        f"{line[match.end() :]}"
    )

    if misspelling.fix and interactivity & 1:
        r = ""
        fixword = fix_case(wrongword, misspelling.data)
        while not r:
            print(
                f"{cfilename}:{cline}: {line_ui}\t{wrongword} ==> {fixword} (Y/n/a/s) ",
                end="",
                flush=True,
            )
            answer = sys.stdin.readline()
            if not answer:
                return _no_more_input(misspelling)
            r = answer.strip().upper()
            if not r:
                r = "Y"
            if r not in ("Y", "N", "A", "S"):
                print(
                    "Say 'y' or 'n' for this one, "
                    "'a' or 's' for all of them in this file"
                )
                r = ""

        return r in ("Y", "A"), misspelling.data, r in ("A", "S")

    elif (interactivity & 2) and not misspelling.fix and not misspelling.reason:
        # if it is not disabled, i.e. it just has more than one possible fix,
        # we ask the user which word to use

        r = ""
        remember = False
        opt = [w.strip() for w in misspelling.data.split(",")]
        while not r:
            print(
                f"{cfilename}:{cline}: {line_ui} Choose an option "
                "(blank for none, Na for whole file, s to skip): ",
                end="",
            )
            for i, o in enumerate(opt):
                fixword = fix_case(wrongword, o)
                print(f" {i}) {fixword}", end="")
            print(": ", end="", flush=True)

            answer = sys.stdin.readline()
            if not answer:
                return _no_more_input(misspelling)
            n = answer.strip().lower()
            if not n:
                break
            if n == "s":
                return False, misspelling.data, True

            remember = n.endswith("a")
            try:
                i = int(n[:-1] if remember else n)
                r = opt[i]
            except (ValueError, IndexError):
                print("Not a valid option\n")

        if r:
            return True, r, remember

    return misspelling.fix, misspelling.data, False


def print_context(
    lines: list[str],
    index: int,
    context: tuple[int, int],
) -> None:
    # context = (context_before, context_after)
    for i in range(index - context[0], index + context[1] + 1):
        if 0 <= i < len(lines):
            print(f"{'>' if i == index else ':'} {lines[i].rstrip()}")


def _ignore_word_sub(
    text: str,
    ignore_word_regex: Optional[Pattern[str]],
) -> str:
    if ignore_word_regex:
        text = ignore_word_regex.sub(" ", text)
    return text


def extract_words(
    text: str,
    word_regex: Pattern[str],
    ignore_word_regex: Optional[Pattern[str]],
) -> list[str]:
    return word_regex.findall(_ignore_word_sub(text, ignore_word_regex))


def extract_words_iter(
    text: str,
    word_regex: Pattern[str],
    ignore_word_regex: Optional[Pattern[str]],
) -> list[Match[str]]:
    return list(word_regex.finditer(_ignore_word_sub(text, ignore_word_regex)))


def apply_uri_ignore_words(
    check_matches: list[Match[str]],
    line: str,
    word_regex: Pattern[str],
    ignore_word_regex: Optional[Pattern[str]],
    uri_regex: Pattern[str],
    uri_ignore_words: set[str],
) -> list[Match[str]]:
    if not uri_ignore_words:
        return check_matches
    for uri in uri_regex.findall(line):
        for uri_word in extract_words(uri, word_regex, ignore_word_regex):
            if uri_word in uri_ignore_words:
                # determine/remove only the first among matches
                for i, match in enumerate(check_matches):
                    if match.group() == uri_word:
                        check_matches = check_matches[:i] + check_matches[i + 1 :]
                        break
    return check_matches


def _format_colored_output(
    filename: str,
    colors: TermColors,
    line_num: int,
    wrong: str,
    right: str,
) -> tuple[str, str, str, str]:
    """Format colored strings for output.

    Args:
        filename: The filename being processed.
        colors: TermColors instance for color formatting.
        line_num: Line number (1-based) where the misspelling was found.
        wrong: The misspelled word.
        right: The correct word.

    Returns:
        Tuple of (filename, line_num, wrong_word, right_word) with color codes.
    """
    cfilename = f"{colors.FILE}{filename}{colors.DISABLE}"
    cline = f"{colors.FILE}{line_num}{colors.DISABLE}"
    cwrongword = f"{colors.WWORD}{wrong}{colors.DISABLE}"
    crightword = f"{colors.FWORD}{right}{colors.DISABLE}"
    return cfilename, cline, cwrongword, crightword


def parse_lines(
    fragment: tuple[bool, int, list[str]],
    filename: str,
    colors: TermColors,
    summary: Optional[Summary],
    misspellings: dict[str, Misspelling],
    ignore_words_cased: set[str],
    exclude_lines: set[str],
    word_regex: Pattern[str],
    ignore_word_regex: Optional[Pattern[str]],
    uri_regex: Pattern[str],
    uri_ignore_words: set[str],
    context: Optional[tuple[int, int]],
    options: argparse.Namespace,
    asked_for: dict[str, tuple[bool, str]],
) -> tuple[int, bool, list[tuple[int, str, str]]]:
    bad_count = 0
    changed = False
    changes_made: list[tuple[int, str, str]] = []

    _, fragment_line_number, lines = fragment

    next_line_ignore_words: Optional[set[str]] = None

    for i, line in enumerate(lines):
        line = line.rstrip()
        # Apply any ignore-next-line directive carried from the previous line.
        pending_next_line_ignore = next_line_ignore_words
        next_line_ignore_words = None

        directive_words: set[str] = set()
        if codespell_ignore_next_line_tag in line:
            nl_match = ignore_next_line_regex.search(line)
            if nl_match:
                directive_words = set(
                    filter(None, (nl_match.group("words") or "").split(","))
                )
                next_line_ignore_words = directive_words

        if not line or line in exclude_lines:
            continue
        line_number = fragment_line_number + i

        extra_words_to_ignore: set[str] = set()
        match = (
            inline_ignore_regex.search(line) if codespell_ignore_tag in line else None
        )
        if match:
            extra_words_to_ignore = set(
                filter(None, (match.group("words") or "").split(","))
            )
            if not extra_words_to_ignore:
                continue

        # Words named in an ignore-next-line directive are ignored on its own line too.
        extra_words_to_ignore |= directive_words

        if pending_next_line_ignore is not None:
            if not pending_next_line_ignore:
                continue
            extra_words_to_ignore |= pending_next_line_ignore

        fixed_words = set()

        # If all URI spelling errors will be ignored, erase any URI before
        # extracting words. Otherwise, apply ignores after extracting words.
        # This ensures that if a URI ignore word occurs both inside a URI and
        # outside, it will still be a spelling error.
        if "*" in uri_ignore_words:
            line = uri_regex.sub(" ", line)
        check_matches = extract_words_iter(line, word_regex, ignore_word_regex)
        if "*" not in uri_ignore_words:
            check_matches = apply_uri_ignore_words(
                check_matches,
                line,
                word_regex,
                ignore_word_regex,
                uri_regex,
                uri_ignore_words,
            )
        for match in check_matches:
            word = match.group()
            if word in ignore_words_cased:
                continue
            lword = word.lower()
            if lword in misspellings and lword not in extra_words_to_ignore:
                # Sometimes we find a 'misspelling' which is actually a valid word
                # preceded by a string escape sequence.  Ignore such cases as
                # they're usually false alarms; see issue #17 among others.
                char_before_idx = match.start() - 1
                if (
                    char_before_idx >= 0
                    and line[char_before_idx] == "\\"
                    # bell, backspace, formfeed, newline, carriage-return, tab, vtab.
                    and word.startswith(("a", "b", "f", "n", "r", "t", "v"))
                    and lword[1:] not in misspellings
                ):
                    continue

                # An "[sic]" marker right after the word flags it as an
                # intentional/quoted spelling, so leave it alone.
                if options.ignore_sic and sic_regex.match(line, match.end()):
                    continue

                context_shown = False
                fix = misspellings[lword].fix
                fixword = fix_case(word, misspellings[lword].data)

                if options.interactive:
                    if lword in asked_for:
                        fix, data = asked_for[lword]
                    else:
                        if context is not None:
                            context_shown = True
                            print_context(lines, i, context)
                        fix, data, remember = ask_for_word_fix(
                            lines[i],
                            match,
                            misspellings[lword],
                            options.interactive,
                            colors=colors,
                            filename=filename,
                            lineno=line_number + 1,
                        )
                        if remember:
                            asked_for[lword] = (fix, data)
                    # The answer is uncased: case it for this match.
                    fixword = fix_case(word, data)

                if summary and fix:
                    summary.update(lword)

                if word in fixed_words:  # can skip because of re.sub below
                    continue

                if options.write_changes and fix:
                    new_line = re.sub(rf"\b{word}\b", fixword, lines[i])
                    if new_line != lines[i]:
                        changed = True
                        lines[i] = new_line
                        fixed_words.add(word)
                        changes_made.append((line_number + 1, word, fixword))
                        continue
                    # Not found in the original line (e.g. --ignore-regex split
                    # it out of a larger word), so report it instead (GH-2056).

                # otherwise warning was explicitly set by interactive mode
                if (
                    options.interactive & 2
                    and not fix
                    and not misspellings[lword].reason
                ):
                    continue

                cfilename, cline, cwrongword, crightword = _format_colored_output(
                    filename, colors, line_number + 1, word, fixword
                )

                reason = misspellings[lword].reason
                if reason:
                    if options.quiet_level & QuietLevels.DISABLED_FIXES:
                        continue
                    creason = f"  | {colors.FILE}{reason}{colors.DISABLE}"
                else:
                    if options.quiet_level & QuietLevels.NON_AUTOMATIC_FIXES:
                        continue
                    creason = ""

                # If we get to this point (uncorrected error) we should change
                # our bad_count and thus return value
                bad_count += 1

                if (not context_shown) and (context is not None):
                    print_context(lines, i, context)
                if filename != "-":
                    print(
                        f"{cfilename}:{cline}: {cwrongword} ==> {crightword}{creason}"
                    )
                elif options.stdin_single_line:
                    print(f"{cline}: {cwrongword} ==> {crightword}{creason}")
                else:
                    print(
                        f"{cline}: {line.strip()}\n\t{cwrongword} "
                        f"==> {crightword}{creason}"
                    )

    return bad_count, changed, changes_made


def parse_file(
    filename: str,
    colors: TermColors,
    summary: Optional[Summary],
    misspellings: dict[str, Misspelling],
    ignore_words_cased: set[str],
    exclude_lines: set[str],
    file_opener: FileOpener,
    word_regex: Pattern[str],
    ignore_word_regex: Optional[Pattern[str]],
    uri_regex: Pattern[str],
    uri_ignore_words: set[str],
    context: Optional[tuple[int, int]],
    options: argparse.Namespace,
) -> int:
    bad_count = 0
    fragments = None

    # Read lines.
    if filename == "-":
        f = sys.stdin
        encoding = "utf-8"
        fragments = file_opener.get_lines(f)
    else:
        if options.check_filenames:
            for word in extract_words(filename, word_regex, ignore_word_regex):
                if word in ignore_words_cased:
                    continue
                lword = word.lower()
                if lword not in misspellings:
                    continue
                fix = misspellings[lword].fix
                fixword = fix_case(word, misspellings[lword].data)

                if summary and fix:
                    summary.update(lword)

                cfilename, _, cwrongword, crightword = _format_colored_output(
                    filename, colors, 0, word, fixword
                )

                reason = misspellings[lword].reason
                if reason:
                    if options.quiet_level & QuietLevels.DISABLED_FIXES:
                        continue
                    creason = f"  | {colors.FILE}{reason}{colors.DISABLE}"
                else:
                    if options.quiet_level & QuietLevels.NON_AUTOMATIC_FIXES:
                        continue
                    creason = ""

                bad_count += 1

                print(f"{cfilename}: {cwrongword} ==> {crightword}{creason}")

        # ignore irregular files
        if not os.path.isfile(filename):
            return bad_count

        try:
            text = is_text_file(filename)
        except PermissionError as e:
            print(f"WARNING: {e.strerror}: {filename}", file=sys.stderr)
            return bad_count
        except OSError:
            return bad_count

        if not text:
            if not options.quiet_level & QuietLevels.BINARY_FILE:
                print(f"WARNING: Binary file: {filename}", file=sys.stderr)
            return bad_count
        try:
            fragments, encoding = file_opener.open(filename)
        except OSError:
            return bad_count

    # Parse lines.
    changed = False
    changes_made: list[tuple[int, str, str]] = []
    # Answers given for the whole file ('a'/'s'): lword -> (fix, uncased fix).
    # Plain y/n answers are not remembered here: they are about one match.
    asked_for: dict[str, tuple[bool, str]] = {}
    for fragment in fragments:
        ignore, _, _ = fragment
        if ignore:
            continue

        bad_count_update, changed_update, changes_made_update = parse_lines(
            fragment,
            filename,
            colors,
            summary,
            misspellings,
            ignore_words_cased,
            exclude_lines,
            word_regex,
            ignore_word_regex,
            uri_regex,
            uri_ignore_words,
            context,
            options,
            asked_for,
        )
        bad_count += bad_count_update
        changed = changed or changed_update
        changes_made.extend(changes_made_update)

    # Write out lines, if changed.
    if changed:
        if filename == "-":
            print("---")
            for _, _, lines in fragments:
                for line in lines:
                    print(line, end="")
        else:
            if not options.quiet_level & QuietLevels.FIXES:
                print(
                    f"{colors.FWORD}FIXED:{colors.DISABLE} "
                    f"{colors.FILE}{filename}{colors.DISABLE}",
                    file=sys.stderr,
                )
                for line_num, wrong, right in changes_made:
                    cfilename, cline, cwrongword, crightword = _format_colored_output(
                        filename, colors, line_num, wrong, right
                    )
                    print(
                        f"  {cfilename}:{cline}: {cwrongword} ==> {crightword}",
                        file=sys.stderr,
                    )
            _write_file_atomically(filename, encoding, fragments)

    return bad_count


def _write_file_atomically(
    filename: str,
    encoding: str,
    fragments: Iterable[tuple[Any, Any, list[str]]],
) -> None:
    """Replace *filename* with a same-directory tempfile so a failed write
    cannot leave the original file truncated to zero bytes.
    """
    # Resolve symlinks so we replace the target, not the link itself
    filename = os.path.realpath(filename)
    directory = os.path.dirname(filename)
    try:
        original_mode = stat.S_IMODE(os.stat(filename).st_mode)
    except OSError:
        original_mode = None
    fd, tmp_path = tempfile.mkstemp(prefix=".codespell-", suffix=".tmp", dir=directory)
    try:
        with os.fdopen(fd, "w", encoding=encoding, newline="") as tmp:
            for _, _, lines in fragments:
                tmp.writelines(lines)
        if original_mode is not None:
            os.chmod(tmp_path, original_mode)
        os.replace(tmp_path, filename)
    except Exception:
        try:
            os.unlink(tmp_path)
        except OSError:
            pass
        raise


def flatten_clean_comma_separated_arguments(
    arguments: Iterable[str],
) -> list[str]:
    """
    >>> flatten_clean_comma_separated_arguments(["a, b ,\n c, d,", "e"])
    ['a', 'b', 'c', 'd', 'e']
    >>> flatten_clean_comma_separated_arguments([])
    []
    """
    return [
        item.strip() for argument in arguments for item in argument.split(",") if item
    ]


def _script_main() -> int:
    """Wrap to main() for setuptools."""
    try:
        return main(*sys.argv[1:])
    except KeyboardInterrupt:
        # User has typed CTRL+C
        sys.stdout.write("\n")
        return 130


def _usage_error(parser: argparse.ArgumentParser, message: str) -> int:
    parser.print_usage()
    print(message, file=sys.stderr)
    return EX_USAGE


def _select_builtin_dictionary(builtin_option: str) -> list[str]:
    use = sorted(set(builtin_option.split(",")))
    if "all" in use:
        use = [u for u in use if u != "all"] + [
            builtin[0] for builtin in _builtin_dictionaries
        ]
        use = sorted(set(use))

    use_dictionaries = []
    for u in use:
        for builtin in _builtin_dictionaries:
            if builtin[0] == u:
                use_dictionaries.append(
                    os.path.join(_data_root, f"dictionary{builtin[2]}.txt")
                )
                break
        else:
            raise KeyError(u)
    return use_dictionaries


def main(*args: str) -> int:
    """Contains flow control"""
    try:
        options, parser, used_cfg_files = parse_options(args)
    except configparser.Error as e:
        print(
            f"ERROR: ill-formed config file: {e.message}",
            file=sys.stderr,
        )
        return EX_CONFIG

    # Report used config files
    if not options.quiet_level & QuietLevels.CONFIG_FILES:
        used_basenames = {os.path.basename(cfg_file) for cfg_file in used_cfg_files}
        if "pyproject.toml" in used_basenames and ".codespellrc" in used_basenames:
            print(
                "WARNING: both pyproject.toml and .codespellrc contain "
                "codespell settings; .codespellrc takes precedence",
                file=sys.stderr,
            )
        if len(used_cfg_files) > 0:
            print("Used config files:")
        for ifile, cfg_file in enumerate(used_cfg_files, start=1):
            print(f"    {ifile}: {cfg_file}")

    if options.interactive > 0:
        options.write_changes = True

    if options.regex and options.write_changes:
        return _usage_error(
            parser,
            "ERROR: --write-changes cannot be used together with --regex",
        )
    word_regex = options.regex or word_regex_def
    try:
        word_regex = re.compile(word_regex)
    except re.error as e:
        return _usage_error(
            parser,
            f'ERROR: invalid --regex "{word_regex}" ({e})',
        )

    if options.ignore_regex:
        try:
            ignore_word_regex = re.compile(options.ignore_regex)
        except re.error as e:
            return _usage_error(
                parser,
                f'ERROR: invalid --ignore-regex "{options.ignore_regex}" ({e})',
            )
    else:
        ignore_word_regex = None

    if options.ignore_multiline_regex:
        try:
            ignore_multiline_regex = re.compile(
                options.ignore_multiline_regex, re.DOTALL
            )
        except re.error as e:
            return _usage_error(
                parser,
                f"ERROR: invalid --ignore-multiline-regex "
                f'"{options.ignore_multiline_regex}" ({e})',
            )
    else:
        ignore_multiline_regex = None

    ignore_words, ignore_words_cased = parse_ignore_words_option(
        options.ignore_words_list
    )
    if options.ignore_words:
        ignore_words_files = flatten_clean_comma_separated_arguments(
            options.ignore_words
        )
        for ignore_words_file in ignore_words_files:
            if not os.path.isfile(ignore_words_file):
                return _usage_error(
                    parser,
                    f"ERROR: cannot find ignore-words file: {ignore_words_file}",
                )
            build_ignore_words(ignore_words_file, ignore_words, ignore_words_cased)

    uri_regex = options.uri_regex or uri_regex_def
    try:
        uri_regex = re.compile(uri_regex)
    except re.error as e:
        return _usage_error(
            parser,
            f'ERROR: invalid --uri-regex "{uri_regex}" ({e})',
        )

    uri_ignore_words = set(
        itertools.chain(*parse_ignore_words_option(options.uri_ignore_words_list))
    )

    dictionaries = flatten_clean_comma_separated_arguments(options.dictionary or ["-"])

    use_dictionaries = []
    for dictionary in dictionaries:
        if dictionary == "-":
            try:
                use_dictionaries.extend(_select_builtin_dictionary(options.builtin))
            except KeyError as e:
                return _usage_error(
                    parser,
                    f"ERROR: Unknown builtin dictionary: {e.args[0]}",
                )
        else:
            if not os.path.isfile(dictionary):
                return _usage_error(
                    parser,
                    f"ERROR: cannot find dictionary file: {dictionary}",
                )
            use_dictionaries.append(dictionary)
    misspellings: dict[str, Misspelling] = {}
    for dictionary in use_dictionaries:
        build_dict(dictionary, misspellings, ignore_words)
    colors = TermColors()
    if not options.colors:
        colors.disable()

    summary = Summary() if options.summary else None

    context = None
    if options.context is not None:
        if (options.before_context is not None) or (options.after_context is not None):
            return _usage_error(
                parser,
                "ERROR: --context/-C cannot be used together with "
                "--context-before/-B or --context-after/-A",
            )
        context_both = max(0, options.context)
        context = (context_both, context_both)
    elif (options.before_context is not None) or (options.after_context is not None):
        context_before = 0
        context_after = 0
        if options.before_context is not None:
            context_before = max(0, options.before_context)
        if options.after_context is not None:
            context_after = max(0, options.after_context)
        context = (context_before, context_after)

    exclude_lines: set[str] = set()
    if options.exclude_file:
        exclude_files = flatten_clean_comma_separated_arguments(options.exclude_file)
        for exclude_file in exclude_files:
            build_exclude_hashes(exclude_file, exclude_lines)

    file_opener = FileOpener(
        options.hard_encoding_detection,
        options.quiet_level,
        ignore_multiline_regex,
    )

    glob_match = GlobMatch(
        flatten_clean_comma_separated_arguments(options.skip) if options.skip else []
    )
    try:
        glob_match.match("/random/path")  # does not need a real path
    except re.error:
        return _usage_error(
            parser,
            "ERROR: --skip/-S has been fed an invalid glob, "
            "try escaping special characters",
        )

    bad_count = 0
    for filename in sorted(options.files):
        # ignore hidden files
        if is_hidden(filename, options.check_hidden):
            continue

        if os.path.isdir(filename):
            for root, dirs, files in os.walk(filename):
                if glob_match.match(root):  # skip (absolute) directories
                    dirs.clear()
                    continue
                if is_hidden(root, options.check_hidden):  # dir itself hidden
                    continue
                for file_ in sorted(files):
                    # ignore hidden files in directories
                    if is_hidden(file_, options.check_hidden):
                        continue
                    if glob_match.match(file_):  # skip files
                        continue
                    fname = os.path.join(root, file_)
                    if glob_match.match(fname):  # skip paths
                        continue
                    bad_count += parse_file(
                        fname,
                        colors,
                        summary,
                        misspellings,
                        ignore_words_cased,
                        exclude_lines,
                        file_opener,
                        word_regex,
                        ignore_word_regex,
                        uri_regex,
                        uri_ignore_words,
                        context,
                        options,
                    )

                # skip (relative) directories
                dirs[:] = [
                    dir_
                    for dir_ in dirs
                    if not glob_match.match(dir_)
                    and not is_hidden(dir_, options.check_hidden)
                ]

        elif not glob_match.match(filename):  # skip files
            bad_count += parse_file(
                filename,
                colors,
                summary,
                misspellings,
                ignore_words_cased,
                exclude_lines,
                file_opener,
                word_regex,
                ignore_word_regex,
                uri_regex,
                uri_ignore_words,
                context,
                options,
            )

    if summary:
        print("\n-------8<-------\nSUMMARY:")
        print(summary)
    if options.count:
        print(bad_count, file=sys.stderr)
    return EX_DATAERR if bad_count else EX_OK
