#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributors.

import re

from fenrirscreenreader.core import debug
from fenrirscreenreader.core.i18n import _


class command:
    def __init__(self):
        pass

    def initialize(self, environment):
        self.env = environment
        # Use commandBuffer like other commands
        if "silenceUntilPrompt" not in self.env["commandBuffer"]:
            self.env["commandBuffer"]["silenceUntilPrompt"] = False

    def shutdown(self):
        pass

    def get_description(self):
        return _("Toggle speech silence until shell prompt returns")

    def run(self):
        if self.env["commandBuffer"]["silenceUntilPrompt"]:
            self.disable_silence()
        else:
            self.enable_silence()

    def enable_silence(self):
        self.env["commandBuffer"]["silenceUntilPrompt"] = True
        self.env["runtime"]["OutputManager"].present_text(
            _("Speech silenced until prompt returns"),
            sound_icon="SpeechOff",
            interrupt=True,
        )
        # Disable speech but don't use the normal temp disable that reactivates
        # on keypress
        self.env["runtime"]["SettingsManager"].set_setting(
            "speech", "enabled", "False"
        )

    def disable_silence(self):
        self.env["commandBuffer"]["silenceUntilPrompt"] = False
        # Re-enable speech
        self.env["runtime"]["SettingsManager"].set_setting(
            "speech", "enabled", "True"
        )
        self.env["runtime"]["OutputManager"].present_text(
            _("Speech restored"), sound_icon="SpeechOn", interrupt=True
        )

    def check_for_prompt(self, text):
        """Check if the current line contains a shell prompt pattern"""
        if not self.env["commandBuffer"]["silenceUntilPrompt"]:
            return False

        # First check for exact matches from settings (with backward
        # compatibility)
        try:
            exact_matches = self.env["runtime"]["SettingsManager"].get_setting(
                "prompt", "exact_matches"
            )
            if exact_matches:
                exact_list = [
                    match.strip()
                    for match in exact_matches.split(",")
                    if match.strip()
                ]
                for exactMatch in exact_list:
                    if text.strip() == exactMatch:
                        self.env["runtime"]["DebugManager"].write_debug_out(
                            "found exact prompt match: " + exactMatch,
                            debug.DebugLevel.INFO,
                        )
                        self.disable_silence()
                        return True
        except Exception as e:
            # Prompt section doesn't exist in settings, skip custom exact
            # matches
            pass

        # Get custom patterns from settings (with backward compatibility)
        prompt_patterns = []
        try:
            custom_patterns = self.env["runtime"][
                "SettingsManager"
            ].get_setting("prompt", "custom_patterns")
            # Add custom patterns from settings if they exist
            if custom_patterns:
                custom_list = [
                    pattern.strip()
                    for pattern in custom_patterns.split(",")
                    if pattern.strip()
                ]
                prompt_patterns.extend(custom_list)
        except Exception as e:
            # Prompt section doesn't exist in settings, skip custom patterns
            pass

        # Add default shell prompt patterns
        prompt_patterns.extend(
            [
                r"^\s*\$\s*$",  # Just $ (with whitespace)
                r"^\s*#\s*$",  # Just # (with whitespace)
                r"^\s*>\s*$",  # Just > (with whitespace)
                r".*@.*[\\\$#>]\s*$",
                # Contains @ and ends with prompt char (user@host style)
                r"^\[.*\]\s*[\\\$#>]\s*$",  # [anything]$ style prompts
                # Simple shell names like bash-5.1$
                r"^[a-zA-Z0-9._-]+[\\\$#>]\s*$",
                # Interactive prompt patterns
                # Package manager confirmation prompts
                r".*\?\s*\[[YyNn]/[YyNn]\]\s*$",  # ? [Y/n] or ? [y/N] style
                r".*\?\s*\[[Yy]es/[Nn]o\]\s*$",  # ? [Yes/No] style
                r".*\?\s*\([YyNn]/[YyNn]\)\s*$",  # ? (Y/n) or ? (y/N) style
                r".*\?\s*\([Yy]es/[Nn]o\)\s*$",  # ? (Yes/No) style
                r".*continue\?\s*\[[YyNn]/[YyNn]\].*$",  # "continue? [Y/n]" style
                r".*ok\s*\[[YyNn]/[YyNn]\].*$",  # "Is this ok [y/N]:" style
                # pacman ":: Proceed? [Y/n]" style
                r"^::.*\?\s*\[[YyNn]/[YyNn]\].*$",
                # Authentication prompts
                # [sudo] password for user:
                r"^\[[Ss]udo\]\s*[Pp]assword\s*for\s+.*:\s*$",
                r"^[Pp]assword\s*:\s*$",  # Password:
                r".*[Pp]assword\s*:\s*$",  # general password prompts
                r".*'s\s*[Pp]assword\s*:\s*$",  # user's password:
                r"^[Ee]nter\s+[Pp]assphrase.*:\s*$",  # Enter passphrase:
                # Please enter passphrase:
                r"^[Pp]lease\s+enter\s+[Pp]assphrase.*:\s*$",
                # General confirmation and continuation prompts
                # Press any key to continue
                r"^[Pp]ress\s+any\s+key\s+to\s+continue.*$",
                r"^[Aa]re\s+you\s+sure\?\s*.*$",  # Are you sure?
                r"^[Pp]lease\s+confirm.*$",  # Please confirm
                r".*confirm.*\([YyNn]/[YyNn]\).*$",  # confirm (y/n)
                r".*\([Yy]/[Nn]\)\s*$",  # ends with (Y/n) or (y/N)
            ]
        )

        for pattern in prompt_patterns:
            try:
                if re.search(pattern, text.strip()):
                    self.env["runtime"]["DebugManager"].write_debug_out(
                        "found prompt pattern: " + pattern,
                        debug.DebugLevel.INFO,
                    )
                    self.disable_silence()
                    return True
            except re.error as e:
                # Invalid regex pattern, skip it and log the error
                self.env["runtime"]["DebugManager"].write_debug_out(
                    "Invalid prompt pattern: " + pattern + " Error: " + str(e),
                    debug.DebugLevel.ERROR,
                )
                continue

        return False

    def set_callback(self, callback):
        pass
