# liblouis Braille Translation and Back-Translation Library
#
# Copyright (C) 2017 Bert Frees
#
# This file is part of liblouis.
#
# liblouis is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 2.1 of the License, or
# (at your option) any later version.
#
# liblouis 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
#

from ctypes import *
from itertools import takewhile, zip_longest, chain, tee
izip = zip
izip_longest = zip_longest

from louis import _loader, liblouis, outlenMultiplier
import re
import sqlite3
import sys

def exit_if_not(expression):
    if not expression:
        raise RuntimeError()

exit_if_not(liblouis.lou_charSize() == 4)

liblouis.isLetter.argtypes = (c_wchar,)
liblouis.toLowercase.argtypes = (c_wchar,)
liblouis.toLowercase.restype = c_wchar

def println(line=""):
    sys.stdout.write(("%s\n" % line))

def printerrln(line=""):
    sys.stderr.write(("%s\n" % line))

def validate_chunks(chunked_text):
    return re.search(r"^([^)(|]+|\([^)(|][^)(|]+\))(\|?([^)(|]+|\([^)(|][^)(|]+\)))*$", chunked_text) != None

def print_chunks(text, hyphen_string):
    exit_if_not(len(hyphen_string) == len(text) - 1 and re.search("^[01x]+$", hyphen_string))
    chunked_text = []
    k = 0
    prev_c = None
    for c in hyphen_string:
        if c != prev_c and c == "0":
            chunked_text.append("(")
        chunked_text.append(text[k])
        if c != prev_c and prev_c == "0":
            chunked_text.append(")")
        if c == "1":
            chunked_text.append("|")
        prev_c = c
        k += 1
    chunked_text.append(text[k])
    if (prev_c == "0"):
        chunked_text.append(")")
    return "".join(chunked_text)

def parse_chunks(chunked_text):
    exit_if_not(validate_chunks(chunked_text))
    text, _ = read_text(chunked_text)
    hyphen_string = ["x"] * (len(text) - 1)
    k = 0
    for c in chunked_text:
        if c == "(":
            hyphen_string[k:] = ["0"] * (len(text) - 1 - k)
        elif c == ")":
            hyphen_string[k-1:] =  ["x"] * (len(text) - 1 - (k-1))
        elif c == "|":
            hyphen_string[k-1] = "1"
        else:
            k += 1
            if k > len(text):
                break
    return text, "".join(hyphen_string)

def read_text(maybe_chunked_text):
    if re.search("[)(|]", maybe_chunked_text) != None:
        text = re.sub("[)(|]", "", maybe_chunked_text)
        chunked_text = maybe_chunked_text
    else:
        text = maybe_chunked_text
        chunked_text = None
    return text, chunked_text

def compare_chunks(expected_hyphen_string, actual_hyphen_string, text):
    exit_if_not(len(expected_hyphen_string) == len(text) - 1 and re.search("^[01x]+$", expected_hyphen_string))
    exit_if_not(len(actual_hyphen_string) == len(text) - 1 and re.search("^[01]+$", actual_hyphen_string))
    chunk_errors = my_zip(text,
                          map(lambda e, a: "*" if e in "1x" and a == "1" else
                                           "." if a == "1" else
                                           "-" if e == "1" else None,
                              expected_hyphen_string, actual_hyphen_string))
    return chunk_errors if re.search(r"[-\.]", chunk_errors) else None

# split a string into words consisting of only letters (at least two)
# return an empty list if the provided hyphen string does not have zeros at all positions before and after non-letters
def split_into_words(text, hyphen_string):
    exit_if_not(len(hyphen_string) == len(text) - 1 and re.search("^[01x]+$", hyphen_string))
    words = []
    word_hyphen_strings = []
    word = []
    word_hyphen_string = []
    for c,(h1,h2) in izip(text, pairwise('1' + hyphen_string + '1')):
        if is_letter(c):
            word.append(c)
            word_hyphen_string.append(h1)
        elif h1 not in "1x" or h2 not in "1x":
            return []
        else:
            if len(word) > 1:
                words.append("".join(word))
                word_hyphen_strings.append("".join(word_hyphen_string[1:]))
            word = []
            word_hyphen_string = []
    if len(word) > 1:
        words.append("".join(word))
        word_hyphen_strings.append("".join(word_hyphen_string[1:]))
    return izip(words, word_hyphen_strings)

table = None

def load_table(new_table):
    global table
    table = new_table
    table = table.encode("ASCII") if isinstance(table, str) else bytes(table)
    liblouis.loadTable(table);

def is_letter(text):
    return all([liblouis.isLetter(c) for c in text])

def to_lowercase(text):
    return "".join([liblouis.toLowercase(c) for c in text])

def to_dot_pattern(braille):
    c_braille = create_unicode_buffer(braille)
    c_dots = create_string_buffer(9 * len(braille))
    liblouis.toDotPattern(c_braille, c_dots)
    return c_dots.value.decode('ascii')

def hyphenate(text):
    c_text = create_unicode_buffer(text)
    c_text_len = c_int(len(text))
    c_hyphen_string = create_string_buffer(len(text) + 1)
    exit_if_not(liblouis.lou_hyphenate(table, c_text, c_text_len, c_hyphen_string, 0))
    return "".join(['1' if int(p) % 2 else '0' for p in c_hyphen_string.value[1:]])

def translate(text):
    c_text = create_unicode_buffer(text)
    c_text_len = c_int(len(text))
    braille_len = len(text) * outlenMultiplier
    c_braille = create_unicode_buffer(braille_len)
    c_braille_len = c_int(braille_len)
    max_rules = 16
    c_rules = (c_void_p * max_rules)()
    c_rules_len = c_int(max_rules)
    exit_if_not(liblouis._lou_translateWithTracing(table, c_text, byref(c_text_len), c_braille, byref(c_braille_len),
                                                   None, None, None, None, None, 0, c_rules, byref(c_rules_len)))
    return c_braille.value, c_rules[0:c_rules_len.value]

def get_rule(c_rule_pointer):
    c_rule_string = create_unicode_buffer(u"", 128)
    if not liblouis.printRule(cast(c_rule_pointer, c_void_p), c_rule_string):
        return None
    return tuple(c_rule_string.value.split(" "))

def suggest_chunks(text, braille):
    c_text = create_unicode_buffer(text)
    c_braille = create_unicode_buffer(braille)
    c_hyphen_string = create_string_buffer(len(text) + 2)
    if not liblouis.suggestChunks(c_text, c_braille, c_hyphen_string):
        return None;
    hyphen_string = c_hyphen_string.value.decode('ascii')
    hyphen_string = hyphen_string[1:len(hyphen_string)-1]
    assert len(hyphen_string) == len(text) - 1 and re.search("^[01x]+$", hyphen_string)
    return hyphen_string

def find_relevant_rules(text):
    c_text = create_unicode_buffer(text)
    max_rules = 16
    c_rules = [u""] * max_rules + [None]
    for i in range(0, max_rules):
        c_rules[i] = create_unicode_buffer(c_rules[i], 128)
        c_rules[i] = cast(c_rules[i], c_wchar_p)
    c_rules = (c_wchar_p * (max_rules + 1))(*c_rules)
    liblouis.findRelevantRules(c_text, c_rules)
    return map(lambda x: tuple(x.split(" ")), takewhile(lambda x: x, c_rules))

def open_dictionary(dictionary):
    conn = sqlite3.connect(dictionary)
    c = conn.cursor()
    return conn, c

def filterfalse(predicate, iterable):
    return [x for x in iterable if not predicate(x)]

def partition(pred, iterable):
    t1, t2 = tee(iterable)
    return filterfalse(pred, t1), filter(pred, t2)

def pairwise(iterable):
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

def my_zip(*iterables):
    return "".join([x for x in chain(*izip_longest(*iterables)) if x is not None])

class future:
    def __init__(self, f):
        self.f = f
        self.fut = f
        self.is_realized = False
    def __call__(self):
        if not self.is_realized:
            self.fut = self.f()
            self.is_realized = True
        return self.fut