# Generated from estonian.sbl by Snowball 3.1.0 - https://snowballstem.org/

from .basestemmer import BaseStemmer
from .among import Among


class EstonianStemmer(BaseStemmer):
    '''
    This class implements the stemming algorithm defined by a snowball script.
    Generated from estonian.sbl by Snowball 3.1.0 - https://snowballstem.org/
    '''

    g_V1 = {"a", "e", "i", "o", "u", "ä", "õ", "ö", "ü"}

    g_RV = {"'", "a", "e", "i", "o", "u"}

    g_KI = {"b", "d", "f", "g", "h", "k", "p", "s", "t", "z", "š", "ž"}

    g_GI = {"a", "c", "e", "i", "j", "l", "m", "n", "o", "q", "r", "u", "v", "w", "x", "ä", "õ", "ö", "ü"}

    I_p1 = 0

    def __r_mark_regions(self):
        self.I_p1 = self.limit
        while True:
            v_1 = self.cursor
            try:
                if self.cursor + 2 > self.limit:
                    raise lab0()
                self.cursor += 2
                while True:
                    try:
                        if self.cursor == self.limit or self.current[self.cursor] != "'":
                            raise lab1()
                        self.cursor += 1
                        break
                    except lab1: pass
                    if self.cursor >= self.limit:
                        raise lab0()
                    self.cursor += 1
                break
            except lab0: pass
            self.cursor = v_1
            if not self.go_out_grouping(EstonianStemmer.g_V1):
                return False
            self.cursor += 1
            if not self.go_in_grouping(EstonianStemmer.g_V1):
                return False
            self.cursor += 1
            break
        self.I_p1 = self.cursor
        return True

    def __r_emphasis(self):
        if self.cursor < self.I_p1:
            return False
        v_2 = self.limit_backward
        self.limit_backward = self.I_p1
        self.ket = self.cursor
        among_var = self.find_among_b(EstonianStemmer.a_0)
        if among_var == 0:
            self.limit_backward = v_2
            return False
        self.bra = self.cursor
        self.limit_backward = v_2
        v_3 = self.limit - self.cursor
        if self.cursor - 4 < self.limit_backward:
            return False
        self.cursor -= 4
        self.cursor = self.limit - v_3
        if among_var == 1:
            v_4 = self.limit - self.cursor
            if not self.in_grouping_b(EstonianStemmer.g_GI):
                return False
            self.cursor = self.limit - v_4
            v_5 = self.limit - self.cursor
            try:
                if not self.__r_LONGV():
                    raise lab0()
                return False
            except lab0: pass
            self.cursor = self.limit - v_5
            self.slice_del()
        else:
            if not self.in_grouping_b(EstonianStemmer.g_KI):
                return False
            self.slice_del()
        return True

    def __r_verb(self):
        if self.cursor < self.I_p1:
            return False
        v_2 = self.limit_backward
        self.limit_backward = self.I_p1
        self.ket = self.cursor
        among_var = self.find_among_b(EstonianStemmer.a_1)
        if among_var == 0:
            self.limit_backward = v_2
            return False
        self.bra = self.cursor
        self.limit_backward = v_2
        if among_var == 1:
            self.slice_del()
        elif among_var == 2:
            self.slice_from("a")
        else:
            if not self.in_grouping_b(EstonianStemmer.g_V1):
                return False
            self.slice_del()
        return True

    def __r_LONGV(self):
        return self.find_among_b(EstonianStemmer.a_2) != 0

    def __r_i_plural(self):
        if self.cursor < self.I_p1:
            return False
        v_2 = self.limit_backward
        self.limit_backward = self.I_p1
        self.ket = self.cursor
        if self.cursor <= self.limit_backward or self.current[self.cursor - 1] != "i":
            self.limit_backward = v_2
            return False
        self.cursor -= 1
        self.bra = self.cursor
        self.limit_backward = v_2
        if not self.in_grouping_b(EstonianStemmer.g_RV):
            return False
        self.slice_del()
        return True

    def __r_special_noun_endings(self):
        if self.cursor < self.I_p1:
            return False
        v_2 = self.limit_backward
        self.limit_backward = self.I_p1
        self.ket = self.cursor
        among_var = self.find_among_b(EstonianStemmer.a_3)
        if among_var == 0:
            self.limit_backward = v_2
            return False
        self.bra = self.cursor
        self.limit_backward = v_2
        self.slice_from(EstonianStemmer.as_3[among_var - 1])
        return True

    def __r_case_ending(self):
        if self.cursor < self.I_p1:
            return False
        v_2 = self.limit_backward
        self.limit_backward = self.I_p1
        self.ket = self.cursor
        among_var = self.find_among_b(EstonianStemmer.a_4)
        if among_var == 0:
            self.limit_backward = v_2
            return False
        self.bra = self.cursor
        self.limit_backward = v_2
        if among_var == 1:
            while True:
                try:
                    if not self.in_grouping_b(EstonianStemmer.g_RV):
                        raise lab0()
                    break
                except lab0: pass
                if not self.__r_LONGV():
                    return False
                break
        else:
            v_3 = self.limit - self.cursor
            if self.cursor - 4 < self.limit_backward:
                return False
            self.cursor -= 4
            self.cursor = self.limit - v_3
        self.slice_del()
        return True

    def __r_plural_three_first_cases(self):
        if self.cursor < self.I_p1:
            return False
        v_2 = self.limit_backward
        self.limit_backward = self.I_p1
        self.ket = self.cursor
        among_var = self.find_among_b(EstonianStemmer.a_6)
        if among_var == 0:
            self.limit_backward = v_2
            return False
        self.bra = self.cursor
        self.limit_backward = v_2
        if among_var == 1:
            self.slice_from("iku")
        elif among_var == 2:
            v_3 = self.limit - self.cursor
            try:
                if not self.__r_LONGV():
                    raise lab0()
                return False
            except lab0: pass
            self.cursor = self.limit - v_3
            self.slice_del()
        elif among_var == 3:
            while True:
                v_4 = self.limit - self.cursor
                try:
                    v_5 = self.limit - self.cursor
                    if self.cursor - 4 < self.limit_backward:
                        raise lab0()
                    self.cursor -= 4
                    self.cursor = self.limit - v_5
                    among_var = self.find_among_b(EstonianStemmer.a_5)
                    if among_var == 1:
                        self.slice_from("e")
                    elif among_var == 2:
                        self.slice_del()
                    break
                except lab0: pass
                self.cursor = self.limit - v_4
                self.slice_from("t")
                break
        else:
            while True:
                try:
                    if not self.in_grouping_b(EstonianStemmer.g_RV):
                        raise lab0()
                    break
                except lab0: pass
                if not self.__r_LONGV():
                    return False
                break
            self.slice_del()
        return True

    def __r_nu(self):
        if self.cursor < self.I_p1:
            return False
        v_2 = self.limit_backward
        self.limit_backward = self.I_p1
        self.ket = self.cursor
        if self.find_among_b(EstonianStemmer.a_7) == 0:
            self.limit_backward = v_2
            return False
        self.bra = self.cursor
        self.limit_backward = v_2
        self.slice_del()
        return True

    def __r_undouble_kpt(self):
        if not self.in_grouping_b(EstonianStemmer.g_V1):
            return False
        if self.I_p1 > self.cursor:
            return False
        self.ket = self.cursor
        among_var = self.find_among_b(EstonianStemmer.a_8)
        if among_var == 0:
            return False
        self.bra = self.cursor
        self.slice_from(EstonianStemmer.as_8[among_var - 1])
        return True

    def __r_degrees(self):
        if self.cursor < self.I_p1:
            return False
        v_2 = self.limit_backward
        self.limit_backward = self.I_p1
        self.ket = self.cursor
        among_var = self.find_among_b(EstonianStemmer.a_9)
        if among_var == 0:
            self.limit_backward = v_2
            return False
        self.bra = self.cursor
        self.limit_backward = v_2
        if among_var == 1:
            if not self.in_grouping_b(EstonianStemmer.g_RV):
                return False
            self.slice_del()
        else:
            self.slice_del()
        return True

    def __r_substantive(self):
        v_1 = self.limit - self.cursor
        self.__r_special_noun_endings()
        self.cursor = self.limit - v_1
        v_2 = self.limit - self.cursor
        self.__r_case_ending()
        self.cursor = self.limit - v_2
        v_3 = self.limit - self.cursor
        self.__r_plural_three_first_cases()
        self.cursor = self.limit - v_3
        v_4 = self.limit - self.cursor
        self.__r_degrees()
        self.cursor = self.limit - v_4
        v_5 = self.limit - self.cursor
        self.__r_i_plural()
        self.cursor = self.limit - v_5
        v_6 = self.limit - self.cursor
        self.__r_nu()
        self.cursor = self.limit - v_6
        return True

    def __r_verb_exceptions(self):
        self.bra = self.cursor
        among_var = self.find_among(EstonianStemmer.a_10)
        if among_var == 0:
            return False
        self.ket = self.cursor
        if self.cursor < self.limit:
            return False
        self.slice_from(EstonianStemmer.as_10[among_var - 1])
        return True

    def _stem(self):
        v_1 = self.cursor
        try:
            if not self.__r_verb_exceptions():
                raise lab0()
            return False
        except lab0: pass
        self.cursor = v_1
        v_2 = self.cursor
        self.__r_mark_regions()
        self.cursor = v_2
        self.limit_backward = self.cursor
        self.cursor = self.limit
        v_3 = self.limit - self.cursor
        self.__r_emphasis()
        self.cursor = self.limit - v_3
        v_4 = self.limit - self.cursor
        try:
            while True:
                v_5 = self.limit - self.cursor
                try:
                    if not self.__r_verb():
                        raise lab1()
                    break
                except lab1: pass
                self.cursor = self.limit - v_5
                self.__r_substantive()
                break
        except lab0: pass
        self.cursor = self.limit - v_4
        v_6 = self.limit - self.cursor
        self.__r_undouble_kpt()
        self.cursor = self.limit - v_6
        self.ket = self.cursor
        if self.cursor <= self.limit_backward or self.current[self.cursor - 1] != "'":
            return False
        self.cursor -= 1
        self.bra = self.cursor
        self.slice_del()
        self.cursor = self.limit_backward
        return True

    a_0 = [
        Among("gi", -1, 1),
        Among("ki", -1, 2)
    ]

    a_1 = [
        Among("da", -1, 3),
        Among("mata", -1, 1),
        Among("b", -1, 3),
        Among("ksid", -1, 1),
        Among("nuksid", 3, 1),
        Among("me", -1, 3),
        Among("sime", 5, 1),
        Among("ksime", 6, 1),
        Among("nuksime", 7, 1),
        Among("akse", -1, 2),
        Among("dakse", 9, 1),
        Among("takse", 9, 1),
        Among("site", -1, 1),
        Among("ksite", 12, 1),
        Among("nuksite", 13, 1),
        Among("n", -1, 3),
        Among("sin", 15, 1),
        Among("ksin", 16, 1),
        Among("nuksin", 17, 1),
        Among("daks", -1, 1),
        Among("taks", -1, 1)
    ]

    a_2 = [
        Among("aa", -1, -1),
        Among("ee", -1, -1),
        Among("ii", -1, -1),
        Among("oo", -1, -1),
        Among("uu", -1, -1),
        Among("ää", -1, -1),
        Among("õõ", -1, -1),
        Among("öö", -1, -1),
        Among("üü", -1, -1)
    ]

    a_3 = [
        Among("lane", -1, 1),
        Among("line", -1, 3),
        Among("mine", -1, 2),
        Among("lasse", -1, 1),
        Among("lisse", -1, 3),
        Among("misse", -1, 2),
        Among("lasi", -1, 1),
        Among("lisi", -1, 3),
        Among("misi", -1, 2),
        Among("last", -1, 1),
        Among("list", -1, 3),
        Among("mist", -1, 2)
    ]
    as_3 = ("lase", "mise", "lise")

    a_4 = [
        Among("ga", -1, 1),
        Among("ta", -1, 1),
        Among("le", -1, 1),
        Among("sse", -1, 1),
        Among("l", -1, 1),
        Among("s", -1, 1),
        Among("ks", 5, 1),
        Among("t", -1, 2),
        Among("lt", 7, 1),
        Among("st", 7, 1)
    ]

    a_5 = [
        Among("", -1, 2),
        Among("las", 0, 1),
        Among("lis", 0, 1),
        Among("mis", 0, 1),
        Among("t", 0, -1)
    ]

    a_6 = [
        Among("d", -1, 4),
        Among("sid", 0, 2),
        Among("de", -1, 4),
        Among("ikkude", 2, 1),
        Among("ike", -1, 1),
        Among("ikke", -1, 1),
        Among("te", -1, 3)
    ]

    a_7 = [
        Among("va", -1, -1),
        Among("du", -1, -1),
        Among("nu", -1, -1),
        Among("tu", -1, -1)
    ]

    a_8 = [
        Among("kk", -1, 1),
        Among("pp", -1, 2),
        Among("tt", -1, 3)
    ]
    as_8 = ("k", "p", "t")

    a_9 = [
        Among("ma", -1, 2),
        Among("mai", -1, 1),
        Among("m", -1, 1)
    ]

    a_10 = [
        Among("joob", -1, 1),
        Among("jood", -1, 1),
        Among("joodakse", 1, 1),
        Among("jooma", -1, 1),
        Among("joomata", 3, 1),
        Among("joome", -1, 1),
        Among("joon", -1, 1),
        Among("joote", -1, 1),
        Among("joovad", -1, 1),
        Among("juua", -1, 1),
        Among("juuakse", 9, 1),
        Among("jäi", -1, 12),
        Among("jäid", 11, 12),
        Among("jäime", 11, 12),
        Among("jäin", 11, 12),
        Among("jäite", 11, 12),
        Among("jääb", -1, 12),
        Among("jääd", -1, 12),
        Among("jääda", 17, 12),
        Among("jäädakse", 18, 12),
        Among("jäädi", 17, 12),
        Among("jääks", -1, 12),
        Among("jääksid", 21, 12),
        Among("jääksime", 21, 12),
        Among("jääksin", 21, 12),
        Among("jääksite", 21, 12),
        Among("jääma", -1, 12),
        Among("jäämata", 26, 12),
        Among("jääme", -1, 12),
        Among("jään", -1, 12),
        Among("jääte", -1, 12),
        Among("jäävad", -1, 12),
        Among("jõi", -1, 1),
        Among("jõid", 32, 1),
        Among("jõime", 32, 1),
        Among("jõin", 32, 1),
        Among("jõite", 32, 1),
        Among("keeb", -1, 4),
        Among("keed", -1, 4),
        Among("keedakse", 38, 4),
        Among("keeks", -1, 4),
        Among("keeksid", 40, 4),
        Among("keeksime", 40, 4),
        Among("keeksin", 40, 4),
        Among("keeksite", 40, 4),
        Among("keema", -1, 4),
        Among("keemata", 45, 4),
        Among("keeme", -1, 4),
        Among("keen", -1, 4),
        Among("kees", -1, 4),
        Among("keeta", -1, 4),
        Among("keete", -1, 4),
        Among("keevad", -1, 4),
        Among("käia", -1, 8),
        Among("käiakse", 53, 8),
        Among("käib", -1, 8),
        Among("käid", -1, 8),
        Among("käidi", 56, 8),
        Among("käiks", -1, 8),
        Among("käiksid", 58, 8),
        Among("käiksime", 58, 8),
        Among("käiksin", 58, 8),
        Among("käiksite", 58, 8),
        Among("käima", -1, 8),
        Among("käimata", 63, 8),
        Among("käime", -1, 8),
        Among("käin", -1, 8),
        Among("käis", -1, 8),
        Among("käite", -1, 8),
        Among("käivad", -1, 8),
        Among("laob", -1, 16),
        Among("laod", -1, 16),
        Among("laoks", -1, 16),
        Among("laoksid", 72, 16),
        Among("laoksime", 72, 16),
        Among("laoksin", 72, 16),
        Among("laoksite", 72, 16),
        Among("laome", -1, 16),
        Among("laon", -1, 16),
        Among("laote", -1, 16),
        Among("laovad", -1, 16),
        Among("loeb", -1, 14),
        Among("loed", -1, 14),
        Among("loeks", -1, 14),
        Among("loeksid", 83, 14),
        Among("loeksime", 83, 14),
        Among("loeksin", 83, 14),
        Among("loeksite", 83, 14),
        Among("loeme", -1, 14),
        Among("loen", -1, 14),
        Among("loete", -1, 14),
        Among("loevad", -1, 14),
        Among("loob", -1, 7),
        Among("lood", -1, 7),
        Among("loodi", 93, 7),
        Among("looks", -1, 7),
        Among("looksid", 95, 7),
        Among("looksime", 95, 7),
        Among("looksin", 95, 7),
        Among("looksite", 95, 7),
        Among("looma", -1, 7),
        Among("loomata", 100, 7),
        Among("loome", -1, 7),
        Among("loon", -1, 7),
        Among("loote", -1, 7),
        Among("loovad", -1, 7),
        Among("luua", -1, 7),
        Among("luuakse", 106, 7),
        Among("lõi", -1, 6),
        Among("lõid", 108, 6),
        Among("lõime", 108, 6),
        Among("lõin", 108, 6),
        Among("lõite", 108, 6),
        Among("lööb", -1, 5),
        Among("lööd", -1, 5),
        Among("löödakse", 114, 5),
        Among("löödi", 114, 5),
        Among("lööks", -1, 5),
        Among("lööksid", 117, 5),
        Among("lööksime", 117, 5),
        Among("lööksin", 117, 5),
        Among("lööksite", 117, 5),
        Among("lööma", -1, 5),
        Among("löömata", 122, 5),
        Among("lööme", -1, 5),
        Among("löön", -1, 5),
        Among("lööte", -1, 5),
        Among("löövad", -1, 5),
        Among("lüüa", -1, 5),
        Among("lüüakse", 128, 5),
        Among("müüa", -1, 13),
        Among("müüakse", 130, 13),
        Among("müüb", -1, 13),
        Among("müüd", -1, 13),
        Among("müüdi", 133, 13),
        Among("müüks", -1, 13),
        Among("müüksid", 135, 13),
        Among("müüksime", 135, 13),
        Among("müüksin", 135, 13),
        Among("müüksite", 135, 13),
        Among("müüma", -1, 13),
        Among("müümata", 140, 13),
        Among("müüme", -1, 13),
        Among("müün", -1, 13),
        Among("müüs", -1, 13),
        Among("müüte", -1, 13),
        Among("müüvad", -1, 13),
        Among("näeb", -1, 18),
        Among("näed", -1, 18),
        Among("näeks", -1, 18),
        Among("näeksid", 149, 18),
        Among("näeksime", 149, 18),
        Among("näeksin", 149, 18),
        Among("näeksite", 149, 18),
        Among("näeme", -1, 18),
        Among("näen", -1, 18),
        Among("näete", -1, 18),
        Among("näevad", -1, 18),
        Among("nägema", -1, 18),
        Among("nägemata", 158, 18),
        Among("näha", -1, 18),
        Among("nähakse", 160, 18),
        Among("nähti", -1, 18),
        Among("põeb", -1, 15),
        Among("põed", -1, 15),
        Among("põeks", -1, 15),
        Among("põeksid", 165, 15),
        Among("põeksime", 165, 15),
        Among("põeksin", 165, 15),
        Among("põeksite", 165, 15),
        Among("põeme", -1, 15),
        Among("põen", -1, 15),
        Among("põete", -1, 15),
        Among("põevad", -1, 15),
        Among("saab", -1, 2),
        Among("saad", -1, 2),
        Among("saada", 175, 2),
        Among("saadakse", 176, 2),
        Among("saadi", 175, 2),
        Among("saaks", -1, 2),
        Among("saaksid", 179, 2),
        Among("saaksime", 179, 2),
        Among("saaksin", 179, 2),
        Among("saaksite", 179, 2),
        Among("saama", -1, 2),
        Among("saamata", 184, 2),
        Among("saame", -1, 2),
        Among("saan", -1, 2),
        Among("saate", -1, 2),
        Among("saavad", -1, 2),
        Among("sai", -1, 2),
        Among("said", 190, 2),
        Among("saime", 190, 2),
        Among("sain", 190, 2),
        Among("saite", 190, 2),
        Among("sõi", -1, 9),
        Among("sõid", 195, 9),
        Among("sõime", 195, 9),
        Among("sõin", 195, 9),
        Among("sõite", 195, 9),
        Among("sööb", -1, 9),
        Among("sööd", -1, 9),
        Among("söödakse", 201, 9),
        Among("söödi", 201, 9),
        Among("sööks", -1, 9),
        Among("sööksid", 204, 9),
        Among("sööksime", 204, 9),
        Among("sööksin", 204, 9),
        Among("sööksite", 204, 9),
        Among("sööma", -1, 9),
        Among("söömata", 209, 9),
        Among("sööme", -1, 9),
        Among("söön", -1, 9),
        Among("sööte", -1, 9),
        Among("söövad", -1, 9),
        Among("süüa", -1, 9),
        Among("süüakse", 215, 9),
        Among("teeb", -1, 17),
        Among("teed", -1, 17),
        Among("teeks", -1, 17),
        Among("teeksid", 219, 17),
        Among("teeksime", 219, 17),
        Among("teeksin", 219, 17),
        Among("teeksite", 219, 17),
        Among("teeme", -1, 17),
        Among("teen", -1, 17),
        Among("teete", -1, 17),
        Among("teevad", -1, 17),
        Among("tegema", -1, 17),
        Among("tegemata", 228, 17),
        Among("teha", -1, 17),
        Among("tehakse", 230, 17),
        Among("tehti", -1, 17),
        Among("toob", -1, 10),
        Among("tood", -1, 10),
        Among("toodi", 234, 10),
        Among("tooks", -1, 10),
        Among("tooksid", 236, 10),
        Among("tooksime", 236, 10),
        Among("tooksin", 236, 10),
        Among("tooksite", 236, 10),
        Among("tooma", -1, 10),
        Among("toomata", 241, 10),
        Among("toome", -1, 10),
        Among("toon", -1, 10),
        Among("toote", -1, 10),
        Among("toovad", -1, 10),
        Among("tuua", -1, 10),
        Among("tuuakse", 247, 10),
        Among("tõi", -1, 10),
        Among("tõid", 249, 10),
        Among("tõime", 249, 10),
        Among("tõin", 249, 10),
        Among("tõite", 249, 10),
        Among("viia", -1, 3),
        Among("viiakse", 254, 3),
        Among("viib", -1, 3),
        Among("viid", -1, 3),
        Among("viidi", 257, 3),
        Among("viiks", -1, 3),
        Among("viiksid", 259, 3),
        Among("viiksime", 259, 3),
        Among("viiksin", 259, 3),
        Among("viiksite", 259, 3),
        Among("viima", -1, 3),
        Among("viimata", 264, 3),
        Among("viime", -1, 3),
        Among("viin", -1, 3),
        Among("viisime", -1, 3),
        Among("viisin", -1, 3),
        Among("viisite", -1, 3),
        Among("viite", -1, 3),
        Among("viivad", -1, 3),
        Among("võib", -1, 11),
        Among("võid", -1, 11),
        Among("võida", 274, 11),
        Among("võidakse", 275, 11),
        Among("võidi", 274, 11),
        Among("võiks", -1, 11),
        Among("võiksid", 278, 11),
        Among("võiksime", 278, 11),
        Among("võiksin", 278, 11),
        Among("võiksite", 278, 11),
        Among("võima", -1, 11),
        Among("võimata", 283, 11),
        Among("võime", -1, 11),
        Among("võin", -1, 11),
        Among("võis", -1, 11),
        Among("võite", -1, 11),
        Among("võivad", -1, 11)
    ]
    as_10 = ("joo", "saa", "viima", "keesi", "löö", "lõi", "loo", "käisi", "söö", "too", "võisi", "jääma", "müüsi", "luge", "põde", "ladu", "tegi", "nägi")


class lab0(BaseException): pass


class lab1(BaseException): pass
