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

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

import os
import string

from fenrirscreenreader.core.i18n import _
from fenrirscreenreader.utils import word_utils

initialized = False
try:
    import enchant

    initialized = True
except Exception as e:
    pass


class command:
    def __init__(self):
        self.language = ""
        self.spellChecker = ""

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

    def shutdown(self):
        pass

    def get_description(self):
        return "No Description found"

    def update_spell_language(self):
        if not initialized:
            return
        self.spellChecker = enchant.Dict(
            self.env["runtime"]["SettingsManager"].get_setting(
                "general", "spell_check_language"
            )
        )
        self.language = self.env["runtime"]["SettingsManager"].get_setting(
            "general", "spell_check_language"
        )

    def run(self):
        if not initialized:
            return
        if not self.env["runtime"]["SettingsManager"].get_setting_as_bool(
            "general", "auto_spell_check"
        ):
            return
        if (
            self.env["runtime"]["SettingsManager"].get_setting(
                "general", "spell_check_language"
            )
            != self.language
        ):
            try:
                self.update_spell_language()
            except Exception as e:
                return

        # just when horizontal cursor move worddetection is needed
        if not self.env["runtime"][
            "CursorManager"
        ].is_cursor_horizontal_move():
            return

        # for now no new line
        if self.env["runtime"]["CursorManager"].is_cursor_vertical_move():
            return
        # more than a keyecho?
        if len(self.env["screen"]["new_delta"]) > 1:
            return
        # deletion
        if self.env["runtime"]["ScreenManager"].is_negative_delta():
            return
        # first place could not be the end of a word
        if self.env["screen"]["new_cursor"]["x"] == 0:
            return

        # get the word (just for speedup only look at current line
        new_content = self.env["screen"]["new_content_text"].split("\n")[
            self.env["screen"]["new_cursor"]["y"]
        ]
        x, y, curr_word, end_of_screen, line_break = (
            word_utils.get_current_word(
                self.env["screen"]["new_cursor"]["x"], 0, new_content
            )
        )
        # was this a typed word?
        if self.env["runtime"]["ScreenManager"].is_delta():
            if not (
                new_content[self.env["screen"]["old_cursor"]["x"]]
                in string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~'
                and x != self.env["screen"]["old_cursor"]["x"]
            ):
                return
            else:
                curr_word = curr_word.strip(
                    string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~'
                )
        else:
            # or just arrow arround?
            if not new_content[
                self.env["screen"]["new_cursor"]["x"]
            ].isspace():
                return
            if (
                x + len(curr_word) != self.env["screen"]["new_cursor"]["x"]
            ) and (
                x + len(curr_word) != self.env["screen"]["new_cursor"]["x"] - 1
            ):
                return

        # just on end of word
        if self.env["screen"]["new_cursor"]["x"] > 0:
            if (
                not new_content[
                    self.env["screen"]["old_cursor"]["x"] - 1
                ].lower()
                in string.ascii_lowercase
            ):
                return

        # ignore bash buildins
        if curr_word in [
            "cd",
            "fg",
            "bg",
            "alias",
            "bind",
            "dir",
            "caller",
            "buildin",
            "command",
            "declare",
            "echo",
            "enable",
            "help",
            "let",
            "local",
            "logout",
            "mapfile",
            "printf",
            "read",
            "readarray",
            "source",
            "type",
            "typeset",
            "ulimit",
            "unalias",
        ]:
            return
        # ignore the application name
        if curr_word.upper() == "FENRIR":
            return
        if curr_word[0] == "-":
            return
        if curr_word[0] == "/":
            return
        if curr_word[0] == "#":
            return
        if curr_word.startswith("./"):
            return
        if "@" in curr_word and "." in curr_word:
            return
        if curr_word[0] == "@":
            return
        if curr_word.isnumeric():
            return
        if curr_word.isdecimal():
            return
        if curr_word.isspace():
            return

        try:
            if os.path.exists("/bin/" + curr_word):
                return
        except Exception as e:
            pass
        try:
            if os.path.exists("/usr/bin/" + curr_word):
                return
        except Exception as e:
            pass
        try:
            if os.path.exists("/sbin/" + curr_word):
                return
        except Exception as e:
            pass

        if not self.spellChecker.check(curr_word):
            self.env["runtime"]["OutputManager"].present_text(
                _("misspelled"),
                sound_icon="mispell",
                interrupt=False,
                flush=False,
            )

    def set_callback(self, callback):
        pass
