import sys
sys.path.insert(0, r'../')
import os
import re
import numpy as np
import gensim
from collections import defaultdict
import argparse
from argparse import ArgumentParser
from utilities import readConll, writevec, writey, traversaltree
from data.dataprocessing import streamtw, streamtwElec
from tdparse import lexicon, streamdata, readTang
import warnings

warnings.simplefilter("error")

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
def segment(tw, target):
    tw = ' '.join(tw)
    segs = []
    for seg in re.split(r'(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?|\!|\,)\s', tw):
        for token in seg.split():
            if token == target:
              segs.append(seg.split())
              break
    target_positions = [[i for i, j in enumerate(seg) if j == target] for seg in segs]

    new_segs = []
    for i in xrange(len(target_positions)):
      temp = []
      if len(target_positions[i]) > 1:
        for j in xrange(len(target_positions[i])):
          temp.append(segs[i])
      else:
        temp.append(segs[i])
      new_segs.append(temp)
    
    target_positions = [item for sublist in target_positions for item in sublist]
    new_segs = [item for sublist in new_segs for item in sublist]

    return new_segs, target_positions

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
class targettw(object):
    def __init__(self,w2vf='../resources/wordemb/w2v/c10_w3_s100',
                        sswef='../resources/wordemb/sswe'):
        self.w2v=gensim.models.Word2Vec.load(w2vf) 
        self.sswe=readTang(sswef) 
        self.lexicons=lexicon()

    def emdsswe(self,i,loc,uni,target):
        f=np.array([])    
        l=np.array([])
        r=np.array([])
        t=np.array([])
        ls=np.array([])
        rs=np.array([])
        #embeddings of fulltw features
        f=self.sswe.get(uni,self.sswe['<unk>'])
        #embeddings of  left context features
        if i<loc:
            l=self.sswe.get(uni,self.sswe['<unk>'])
            if self.lexicons.pos.issuperset(set([uni])):
                try:
                    ls=self.sswe[uni]
                except:
                    pass
            if self.lexicons.neg.issuperset(set([uni])):
                try:
                    ls=self.sswe[uni]
                except:
                    pass
        #embbeddings of  target features  
        elif(i==loc):
            t=self.sswe.get(target.replace('_',''),self.sswe['<unk>'])               
            target2=target.split('_')
            for wd in target2:
                ti=self.sswe.get(wd,self.sswe['<unk>'])
                t=np.concatenate([t,ti])
            
        #embbeddings of  right context features
        else:
            r=self.sswe.get(uni,self.sswe['<unk>'])
            if self.lexicons.pos.issuperset(set([uni])):
                try:
                    rs=self.sswe[uni]
                except:
                    pass
            if self.lexicons.neg.issuperset(set([uni])):
                try:
                    rs=self.sswe[uni]
                except:
                    pass 
        return [f,l,t,r,ls,rs]
    def emdw2v(self,i,loc,uni,target):
        f=np.array([])    
        l=np.array([])
        r=np.array([])
        t=np.array([])
        ls=np.array([])
        rs=np.array([])
        try:
            f=self.w2v[uni]
        except:
            pass 
        #embbeddings of  left context features
        if i<loc:
            try:
                l=self.w2v[uni]
            except:
                pass
            try:
                if self.lexicons.pos.issuperset(set([uni])):
                    ls=self.w2v[uni]
            except:
                pass
            try:
                if self.lexicons.neg.issuperset(set([uni])):
                    ls=self.w2v[uni]
            except:
                pass
        #embbeddings of  target feature  
        elif(i==loc):
            try:
                t=self.w2v[target.replace('_','')]
            except:
                pass                
            target2=target.split('_')
            for wd in target2:
                try:
                    ti=self.w2v[wd]
                    t=np.concatenate([t,ti])
                except:
                    pass    
        #embbeddings of  right context features
        else:
            try:
                r=self.w2v[uni]
            except:
                pass
            try:
                if self.lexicons.pos.issuperset(set([uni])):
                    rs=self.w2v[uni]
            except:
                pass
            try:
                if self.lexicons.neg.issuperset(set([uni])):
                    rs=self.w2v[uni]
            except:
                pass   
        return [f,l,t,r,ls,rs]        

    def concattw(self,feature,size,tws,etype,locs,target,emp,emode):
        """ Concatenation of different features
        """
        fullf=np.array([])
        leftf=np.array([])
        rightf=np.array([])
        tarf=np.array([])
        fulltw_maxs=np.array([])
        fulltw_mins=np.array([])
        fulltw_means=np.array([])
        fulltw_prods=np.array([])
        left_maxs=np.array([])
        left_mins=np.array([])
        left_means=np.array([])
        left_prods=np.array([])
        right_maxs=np.array([])
        right_mins=np.array([])
        right_means=np.array([])
        right_prods=np.array([])
        tar_maxs=np.array([])
        tar_mins=np.array([])
        tar_means=np.array([])
        tar_prods=np.array([])
        leftsenti_max=np.array([])
        rightsenti_max=np.array([])
        leftsenti_sum=np.array([])
        rightsenti_sum=np.array([])
        fulltws=np.array([])
        lefts=np.array([])
        rights=np.array([])
        tars=np.array([])
        leftsentis=np.array([])
        rightsentis=np.array([])
        for a in range(len(locs)):
          if emode=='full':
            tw = t
ws
          else:
            tw = tws[a]
          loc = locs[a]
          fulltw=np.array(
[])
          left=np.array([])
          right=np.array([])
          tar=np.array([])
          leftsenti=np.array([])
          rightsenti=np.array([])
          for i,uni in enumerate(tw):
              if etype=='w2v':
                  f,l,t,r,ls,rs=self.emdw2v(i,loc,uni,target)
              if etype=='sswe':
                  f,l,t,r,ls,rs=self.emdsswe(i,loc,uni,target)
              fulltw=np.concatenate([fulltw,f])
              left=np.concatenate([left,l])
              tar=np.concatenate([tar,t])
              right=np.concatenate([right,r])
              leftsenti=np.concatenate([leftsenti,ls])
              rightsenti=np.concatenate([rightsenti,rs])
          #padding 
          if list(left)==[]:
              left=np.zeros((2*size,))
          if list(right)==[]:
              right=np.zeros((2*size,))
          if list(fulltw)==[]:
              fulltw=np.zeros((2*size,)) 
          if list(tar)==[]:
              tar=np.zeros((2*size,))
          
          if len(left)<=size:
              left=np.concatenate([left,np.zeros((size,))])
          if len(right)<=size:
              right=np.concatenate([right,np.zeros((size,))])
          if len(fulltw)<=size:
              fulltw=np.concatenate([fulltw,np.zeros((size,))])
          if len(tar)<=size:
              tar=np.concatenate([tar,np.zeros((size,))])   

          if list(leftsenti)==[]:
              leftsenti=np.zeros((size,))
          if list(rightsenti)==[]:
              rightsenti=np.zeros((size,))       

          fullf=np.append(fullf,fulltw, axis=0)
          leftf=np.append(leftf,left, axis=0)
          rightf=np.append(rightf,right, axis=0)
          tarf=np.append(tarf,tar, axis=0)
          fulltw=fulltw.reshape(len(fulltw)/size,size)
          left=left.reshape(len(left)/size,size)
          right=right.reshape(len(right)/size,size) 
          tar=tar.reshape(len(tar)/size,size)
          leftsenti=leftsenti.reshape(len(leftsenti)/size,size)  