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

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

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


class command:
    def __init__(self):
        pass

    def initialize(self, environment):
        self.env = environment

    def shutdown(self):
        pass

    def get_description(self):
        return "Detects shell prompts for silence until prompt feature"

    def run(self):
        # Only run if silence until prompt is active
        try:
            if (
                "silenceUntilPrompt" in self.env["commandBuffer"]
                and self.env["commandBuffer"]["silenceUntilPrompt"]
            ):
                # Check the current line for prompt patterns
                if self.env["screen"]["new_content_text"]:
                    lines = self.env["screen"]["new_content_text"].split("\n")
                    if lines and self.env["screen"]["new_cursor"]["y"] < len(
                        lines
                    ):
                        current_line = lines[
                            self.env["screen"]["new_cursor"]["y"]
                        ]
                        self.check_for_prompt(current_line)
        except Exception as e:
            # Silently ignore errors to avoid disrupting normal operation
            self.env["runtime"]["DebugManager"].write_debug_out(
                "prompt_detector run: Error in prompt detection: " + str(e),
                debug.DebugLevel.ERROR,
            )

    def check_for_prompt(self, text):
        """Check if the current line contains a shell prompt pattern"""
        import re

        # Debug: Print what we're checking
        self.env["runtime"]["DebugManager"].write_debug_out(
            "Prompt detector checking: '" + text + "'", debug.DebugLevel.INFO
        )

        # 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._restore_speech()
                        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._restore_speech()
                    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 _restore_speech(self):
        """Helper method to restore speech when prompt is detected"""
        # If speech is already enabled, just clear flags to avoid unnecessary
        # interrupts on prompt return
        if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
            "speech", "enabled"
        ):
            self.env["commandBuffer"]["silenceUntilPrompt"] = False
            if "enableSpeechOnKeypress" in self.env["commandBuffer"]:
                self.env["commandBuffer"]["enableSpeechOnKeypress"] = False
            return

        # Disable silence mode
        self.env["commandBuffer"]["silenceUntilPrompt"] = False
        # Also disable the keypress-based speech restoration since we're
        # enabling it now
        if "enableSpeechOnKeypress" in self.env["commandBuffer"]:
            self.env["commandBuffer"]["enableSpeechOnKeypress"] = 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 set_callback(self, callback):
        pass
