from __future__ import print_function,division
import csv,re,codecs
import sys,os
sys.path.append(os.getcwd())

import pandas as pd
def detect_polysachharide(monosaccharide_name_tsv,monosaccharide_short_name_txt,text):

    monosaccharide_name_list=[]
    with open(monosaccharide_name_tsv) as csvfile:
        spamreader = csv.reader(csvfile, delimiter='\t', quotechar='|')

        for row in spamreader:
            col_title=row
            #print(col_title)
            break


        for row in spamreader:
            monosaccharide_name_list.append(row[0])

    monosaccharide_name_list.append('GalNac')
    monosaccharide_name_list.append('GalNAc')
    monosaccharide_name_list.append('4GlcNAc')
    monosaccharide_name_list.append('Mana')
    monosaccharide_name_list.append('2Man')
    monosaccharide_name_list.append('LacdiNAc')
    monosaccharide_name_list.append('lacdiNAc')
    monosaccharide_name_list.append('lacNAc')

    monosaccharide_short_name_list=pd.read_csv(monosaccharide_short_name_txt,header=None,delimiter='\t').iloc[:,0].tolist()
    monosaccharide_short_name_list=list(set(monosaccharide_short_name_list))
    monosaccharide_short_name_lower_list=[mi.lower() for mi in monosaccharide_short_name_list]

    monosaccharide_name_list+=monosaccharide_short_name_list
    monosaccharide_name_list+=monosaccharide_short_name_lower_list
    #sort based on the length of the string
    monosaccharide_name_list.sort(key=lambda x:len(x),reverse=True)
    #print(monosaccharide_name_list)
    mono_pattern='|'.join(monosaccharide_name_list)
    mono_pattern='('+mono_pattern+')'

    com_pattern1=re.compile(mono_pattern)

    sr=com_pattern1.search(text)
    #find that the word "Digestion", "Neu~", etc, might be detected as monosachharide
    #so we need to check the letter just after the mps to make sure it is not regular word
    lower_letter=[]
    for i in range(ord('a'),ord('a')+26):
        lower_letter.append(chr(i))
    #print(sr)
    span_list=[]
    while sr:
        #print(sr.span(),'-',sr.group(0))
        #print(sr.span()[1],'-',text[sr.span()[1]])

        span_list.append(sr.span())
        if (sr.span()[1]<len(text) and text[sr.span()[1]] in lower_letter) or (sr.span()[0]>0 and text[sr.span()[0]-1] in lower_letter):
            span_list.pop()
        sr=com_pattern1.search(text,pos=sr.span()[1])
    #mono_name=[text[si[0]:si[1]] for si in span_list]
    found_poly_span_list=[]
    if span_list:
        #print("Found mono:",span_list)
        #print("Found mono name:",mono_name)
        if len(span_list)>1:
            found_poly_span_list=detect_string_between_monosacharide2(text,span_list)
        else:
            found_poly_span_list=span_list
        # findall might not be a good function here
        #m1=re.findall(mono_pattern,text)
        #print(m1)
    '''
    #detect cores and motifs here
    motifFile='motif.txt'

    motif_list=pd.read_csv(motifFile,header=None,delimiter='\t').iloc[:,0].tolist()
    core_motif_name_list=motif_list
    #sort based on the length of the string
    core_motif_name_list.sort(key=lambda x:len(x),reverse=True)

    core_motif_pattern='|'.join(core_motif_name_list)
    core_motif_pattern='('+core_motif_pattern+')'

    com_pattern_mt=re.compile(core_motif_pattern)

    sr_mt=com_pattern_mt.search(text)

    #so we need to check the letter just after the mps to make sure it is not regular word
    lower_letter=[]
    for i in range(ord('a'),ord('a')+26):
        lower_letter.append(chr(i))
    #print(sr)
    span_list=[]
    while sr:
        #print(sr.span(),'-',sr.group(0))
        #print(sr.span()[1],'-',text[sr.span()[1]])

        span_list.append(sr_mt.span())
        if sr_mt.span()[1]<len(text) and text[sr_mt.span()[1]] in lower_letter:
            span_list.pop()
        sr_mt=com_pattern_mt.search(text,pos=sr_mt.span()[1])
    '''
    #add the detected cores and motifs
    #sssfound_poly_span_list+=span_list
    found_poly_list=[]
    new_found_poly_span_list=[]
    for fi in found_poly_span_list:
        #deal with the begining and end of a  polysaccharide
        fi=add_begin_end_string(text, fi)
        if text[fi[0]:fi[1]].endswith('ase') or text[fi[0]:fi[1]]=='all' or text[fi[0]:fi[1]]=='All':
            continue

        found_poly_list.append(text[fi[0]:fi[1]])
        new_found_poly_span_list.append((fi[0],fi[1]))
    #print('Found Polysacharide:',found_poly_list)

    return found_poly_list,new_found_poly_span_list


def add_begin_end_string(text, span_tuple):
    new_tuple=list(span_tuple)
    while new_tuple[0]>0 and text[new_tuple[0]-1]!=' ':
        new_tuple[0]=new_tuple[0]-1

    while new_tuple[1]<len(text) and text[new_tuple[1]]!=' ' and text[new_tuple[1]]!=',' and text[new_tuple[1]]!='.':
        new_tuple[1]=new_tuple[1]+1
    return tuple(new_tuple)


def detect_string_between_monosacharide(text,span_list):

    #detect the pattern between monosaccharide
    found_poly_span_list=[]
    bet_pattern=['B?-?\(?\d+->?\d+\)?\(?', \
                 '(\(alpha\))?(\(beta\))?\d+->?\d+\)?\(?', \
                 '\)?\d+\(?\[?', \
                 '\d+\(\d*\)', \
                 '\((alpha)?(beta)? \d+-\d*\)\]?\[?', \
                 ]

    cur_start=span_list[0][0]
    best_pattern=''
    for i in range(len(span_list)-1):
        bet_span=(span_list[i][1],span_list[i+1][0])
        bet_str_len=span_list[i+1][0]-span_list[i][1]
        #choose the best pattern for use
        for pi in range(len(bet_pattern)):
            complie_pattern=re.compile(bet_pattern[pi])
            sr=complie_pattern.search(text,pos=bet_span[0],endpos=bet_span[1])
            if sr is None:
                continue
            if pi <len(bet_pattern)-1 and len(sr.group())!=bet_str_len:
                continue
            elif pi ==len(bet_pattern)-1 and len(sr.group())!=bet_str_len:
                print('Cannot find a good pattern!')
            elif len(sr.group())==bet_str_len:
                best_pattern=bet_pattern[pi]
                break
        if best_pattern!='':
            break
    complie_best_pattern=re.compile(best_pattern)


    for i in range(len(span_list)-1):
        bet_span=(span_list[i][1],span_list[i+1][0])


        sr=complie_best_pattern.search(text,pos=bet_span[0],endpos=bet_span[1])

        if not sr:

            found_poly_span_list.append((cur_start,span_list[i][1]))
            cur_start=span_list[i+1][0]
    found_poly_span_list.append((cur_start,span_list[i+1][1]))

    #print(found_poly_span_list)
    return found_poly_span_list

def detect_string_between_monosacharide2(text,span_list):
    #detect the pattern between monosaccharide
    found_poly_span_list=[]
    bet_pattern_none='([^a-zA-Z]*)(A?c?\s?[a-zA-Z\,\.]+)([^a-zA-Z]*)([ a-zA-Z\,\.]*)'
    complie_pattern=re.compile(bet_pattern_none)
    cur_start=span_list[0][0]

    key_word=['alpha','beta','B','Ac','Ac alpha','leads to', '']
    for i in range(len(span_list)-1):
        bet_span=(span_list[i][1],span_list[i+1][0])

        #print(text[bet_span[0]:bet_span[1]])
        sr=complie_pattern.search(text,pos=bet_span[0],endpos=bet_span[1])
        #if sr is not None:
        #    print(sr,'-',sr.group(2),'-',sr.group(4))

        if sr is not None:
            bet_str1=sr.group(2)
            bet_str2=sr.group(4)

            if bet_str1.strip() not in key_word or bet_str2.strip() not in key_word:


                found_poly_span_list.append((cur_start,span_list[i][1]))
                cur_start=span_list[i+1][0]
    found_poly_span_list.append((cur_start,span_list[i+1][1]))


    return found_poly_span_list

def get_text_list(file_name=''):
    if file_name=='':
        return []
    text_list=[]
    with open(file_name, newline='') as csvfile:
        spamreader = csv.reader(csvfile, delimiter='\t', quotechar='|')

        for row in spamreader:
            col_title=row
            #print(col_title)
            break


        for row in spamreader:
            #print(row[2])
            if row[2]!='':
                text_list.append(row[2])
    return text_list

if __name__ == '__main__':
    #test
    count=1

    monosaccharide_name_tsv='dictionaries - sugars.tsv'
    monosaccharide_short_name_txt='monosaccharide_short_name.txt'
    '''
    text=get_text_list(file_name='UniCarbKB_set - curation_sheet_Xavier.tsv')
    for ti in text:
        nti=str(count)+'. '+ti

        found_poly_l,span_list=detect_polysachharide(monosaccharide_name_tsv,nti)
        if found_poly_l:
            print(nti)
            print('Found Polysaccharide List:',found_poly_l)
            print(span_list)
            print('\n')
            count+=1

    '''
    text="-catenin is O-GlcNAc glycosylated at Serine 23 :"
    print(len(text))
    found_poly_l,span_list=detect_polysachharide(monosaccharide_name_tsv,monosaccharide_short_name_txt,text)
    if found_poly_l:

        print('Found Polysaccharide List:',found_poly_l)
        #for pi in found_poly_l:
        #    print(len(pi))
        print(span_list)

