import math


def make_char_seqs(word_seqs, vocab=[], oovs={}, pads={}, len_perc=1.0, lower=False):
    """
    Turns word sequences into char sequences
        Inputs:
            - word_seqs: list of sequences of words, represented as [(w1, tag1, x1), ..., (wN, tagN, xN)]
            - vocab: set containing all characters to use as vocabulary
            - oovs: dictionary with aliases to replace oovs with (valid keys: number, unknown)
            - pads: dictionary with delimiter characters to include in words (valid keys: begin, end)
            - len_perc: percentile of allowed word lengths
            - lower: lowercase words in the input data
        Outputs:
            - char_sents: list of sentences represented as [[c1_1, c2_1, ...], ..., [c1_N, c2_N, ...]]
            - max_len: maximum number of characters per word allowed
    """
    char_seqs = []
    lengths = []
    num_chars = 0
    num_oovs = 0
    num_spaces = 0

    for sent in word_seqs:
        # decompose each one of the original words
        chars = []
        wordlist = [w[2] if isinstance(w, (list,tuple)) else w for w in sent]

        # include each word in the sentences as a list of characters
        for word in wordlist:
            chars.append([])
            if lower:
                word = word.lower()
            if 'begin' in pads:
                chars[-1].append(pads['begin'])
            for c in word:
                num_chars += 1
                if vocab and c not in vocab:
                    if c.isspace():
                        num_spaces += 1
                    if c.isdigit():
                        c = oovs['number']
                    else:
                        c = oovs['unknown']
                    num_oovs += 1
                chars[-1].append(c)
            if 'end' in pads:
                chars[-1].append(pads['end'])

        char_seqs.append(chars)
        lengths += [len(x) for x in chars]

    # find the allowed word length
    max_len = sorted(lengths)[math.ceil((len(lengths)-1) * len_perc)]
    print('[INFO] Word length percentile: ' + str(len_perc))
    print('[INFO] Max allowed word length: ' + str(max_len))
    print('[INFO] Number of OOV characters: ' + str(num_oovs) + ' / ' + str(num_chars))
    print('[INFO] Number of OOV spacing characters: ' + str(num_spaces) + ' / ' + str(num_oovs))
    return char_seqs, max_len