#!/usr/bin/env python
# coding: Shift_JIS

# ##############################

# ファイル名: getjotaivalue.py
# 機能: 与えられたCファイルにおいて，ユーザが選択した状態変数が取りうる値を全て取得する．また，状態変数の更新が起こるときのイベントを全て取得する．
# 関数: separate, getjotaivalue
# 著者名: 山本椋太，若林丈紘

# ##############################

import re
import sys

# ==のみ考えている
# ==が複数ある場合は考えてない
# 左辺ないし右辺に変数だけの数式が存在する．
### すなわち，if(state == 1) はありうるが，
### if(state+1 == 2)は存在しないこととしている

# ##############################

# 関数名: separate
# 機能: 状態値を取得する．
# 引数
#   val: 状態変数
#   formula: 解析中の文字列

# ##############################

def separate(val, formula):
    formula = formula.replace(" ","")
    if "==" in formula:
        row = formula.split("==")
        if re.search("\(?"+val+"$",row[0]):
            return row[1][:-1]
    else:
        if formula == "else":
            return "ELSE"

# ##############################

# 関数名: getjotaivalue
# 機能: 与えられたCファイルにおいて，ユーザが選択した状態変数が取りうる値を全て取得する．また，状態変数の更新が起こるときのイベントを全て取得する．
# 引数
#   param: 状態変数
#   directory: 解析対象の関数に関する情報がまとめられたディレクトリ

# ##############################

def getjotaivalue(param,directory):

    print("\n===============")
    print("getjotaivalue")
    print("===============\n")

    out_directory = "temp/" + directory + "/"

    rfile = out_directory + "stm_idlist.tsv"
    fi = open(rfile)
    idlist = fi.readlines()
    fi.close()
    for i,il in enumerate(idlist):
        idlist[i] = il.replace("\n","")

    rfile = out_directory + "stm_stlist.tsv"
    fi = open(rfile)
    stlist = fi.readlines()
    fi.close()
    for i,st in enumerate(stlist):
        stlist[i] = st.replace("\n","")


    rfile = out_directory + "stm_sequence.tsv"
    fi = open(rfile)
    sequence = fi.readlines()
    fi.close()
    for i,sq in enumerate(sequence):
        sequence[i] = sq.replace("\n","")

    ##ここまで表作成情報の整形

    ##ここから状態値の取得
    jotailist = list()
    print("idlist",idlist)
    for il in idlist:
        code = il.split("\t")[1]
        if param in code:
            jotailist.append(il)
        elif re.match("else\t*",code):
            if len(jotailist) == 0:
                continue
            elrow = il.split("\t")
            rjotailist = jotailist[:]
            rjotailist.reverse()

            for rjl in rjotailist:
                row = rjl.split("\t")
                if int(elrow[2]) > int(row[2]):
                    break
                elif int(elrow[2]) < int(row[2]):
                    continue
                else:
                    jotailist.append(il)
                    break
    print("jotailist",jotailist)
    #ここから，表示するべきIDの取得
    targetlist= list()


    #関数を除く，依存関数を取得
    for i, jl in enumerate(jotailist):
        row = jl.split("\t")
        idnum = int(row[0][2:])
        targetlist.append(jl)

        if i+1 == len(jotailist):
            for il in idlist[idnum:]:
                rowi = il.split("\t")
                if int(row[2]) >= int(rowi[2]):
                    break
                targetlist.append(il)
        else:
            nextrow = jotailist[i+1].split("\t")
            nextidnum = int(nextrow[0][2:])
            for j in range(idnum,nextidnum-1):
                targetlist.append(idlist[j])
    print("targetlist",targetlist)
#    input()

    #イベントの取得
    #表示対象にイベントを追加しておく
    eventlist = list()
    for i, jl in enumerate(jotailist):
#        print('test',jotailist)
#        input()
        row = jl.split("\t")
        ridlist = idlist[:int(row[0][2:])]
        nest = int(row[2])
        ridlist.reverse()
        cur_deepest = nest
        for ril in ridlist:
            if ril in jotailist[:i]: continue
            rowril = ril.split("\t")

            if int(rowril[2]) < nest:
                if rowril[2] == '0':
                    break
                if ril not in eventlist:
#                if ril not in targetlist:
                    eventlist.append(ril)
                if ril in targetlist:
                    targetlist.remove(ril)
                if rowril[2] == '1' and re.match('if[ ]*\(', rowril[1]):
                    break

#                if rowril[2] == '0':
#                    break
#    print('------------evtlist------------\n',eventlist)
#    input()
    #関連する関数の取得
    for i, jl in enumerate(jotailist):
        row = jl.split("\t")
        ridlist = idlist[:int(row[0][2:])]
        ridlist.reverse()
        for ril in ridlist:
            if ril in jotailist[:i]: break
            rowril = ril.split("\t")
            if rowril[2] == '0':
                if ril not in targetlist:
                    targetlist.append(ril)
                    break


    #ID昇順にtargetlistのソート
    #IDがstrだと1,10,11,...という順番になるため，intに変換してからソートする
    target_tuplelist=[]
    for t in targetlist:
        tabindex = t.find("\t")
        IDnum = t[2:tabindex]
        target_tuplelist.append((int(IDnum),t))
    target_tuplelist.sort(key=lambda x:(x[0]))
    targetlist = [tuple[1] for tuple in target_tuplelist]


    #ネストの再設定
    for i,tl in enumerate(targetlist):
        row = tl.split("\t")
        if int(row[2]) == 0:
            row2 = targetlist[i+1].split("\t")
            offset = int(row2[2]) - 1
        else:
            row[2] = str(int(row[2]) - offset)
            targetlist[i] = row[0]+"\t"+row[1]+"\t"+row[2]
    print("targetlist",targetlist)


    #表示するIDだけを格納したリストの作成
    targetonlyid = list()
    for tl in targetlist:
        row = tl.split("\t")
        targetonlyid.append(row[0])

    #表示するIDだけで構成されるseqの作成
    newsequence = list()
    for i,seq in enumerate(sequence):
        row = seq.split("\t")
        if row[0] not in targetonlyid: continue
        line = ""
        for r in row:
            if r in targetonlyid: line += r + "\t"
            if "ST" in r: line += r + "\t"
        line = line[:-1]
        print(line)
        newsequence.append(line)
    sequence = newsequence

    #状態値の取得
    jotaivalue =list()
    print("jotailist",jotailist)
    for jl in jotailist:
        row = jl.split("\t")
        value = separate(param,row[1])
        if value not in jotaivalue:
            jotaivalue.append(value) #現在，==のみ対応
        #jotaivalue.append(value) #現在，==のみ対応

    #新しいstlistの作成


    # (changed 2017_0330_wakabayashi)
    # sequenceのある行に複数のSTがある場合,
    # それらのSTを改行文字($$NL$$)で結合してstlistを作る
    # (sequenceのST番号振り直しは後に行う)

    # 変更前
    # newstlist = list()
    # for seq in sequence:
    #     row = seq.split("\t")
    #     for r in row:
    #         print(row)
    #         if "ST" in r:
    #             newstlist.append(stlist[int(r[2:])-1])
    # stlist = newstlist

    newstlist = list()
    stcnt = 1
    st_pre_post_nums = []
    for seq in sequence:
        temp_st = ""
        row = seq.split("\t")
        for r in row:
            if "ST" in r:
                stnum = int(r[2:])
                if temp_st == "":
                    temp_st = stlist[stnum-1]
                else:
                    temp_st = temp_st + "$$NL$$" + stlist[stnum-1]

                st_pre_post_nums.append(("ST" + str(stnum), "ST" + str(stcnt)))
        if "ST" in seq:
            stcnt += 1
        if temp_st != "":
            newstlist.append(temp_st)
    stlist = newstlist

    # changed 2017_0330_wakabayashi_ここまで


    #sequenceとidlistとjotailistのID番号の振り直し
    fi = open(out_directory + "sequence7.tsv",'r')
    seq = fi.readlines()
    fi.close()

    fi = open(out_directory + "idlist3.tsv",'r')
    lines = fi.readlines()
    fi.close()

    idcnt = 1
    for i,tl in enumerate(targetlist):
        tl = tl.replace("\n","")
        row = tl.split("\t")
        target = row[0]
        regep = target+"(\\t|\\n|$)"

        for j,seq in enumerate(sequence):
            temp = re.sub(regep,"ID"+str(idcnt),seq)
            temp = temp.split("ID")
            if len(temp) == 2:
                temp2 = temp[1].split("ST")
                temp[1] = temp2[0]
                for t2 in temp2[1:]:
                    if "ST"+t2 not in temp:
                        temp.append("ST"+t2)
            result = ""

            for t in temp:
                t = t.replace("\t","")
                if t == '': continue
                if "ST" in t: result += t + "\t"
                else: result += "ID"+t +"\t"
            result = result[:-1].replace("\n","")
            sequence[j] = result
            targetlist[j] = re.sub(regep,"ID"+str(idcnt)+"\t",targetlist[j])
            for k,jl in enumerate(jotailist):
                jotailist[k] = re.sub(regep,"ID"+str(idcnt)+"\t",jl)
            for k,el in enumerate(eventlist):
                eventlist[k] = re.sub(regep,"ID"+str(idcnt)+"\t",el)

        idcnt += 1

    #sequenceのST番号の振り直し
    #(changed 2017_0330_wakabayashi)
    #sequenceの行に複数のSTがある場合に対応

    # 変更前
    #stcnt = 1
    #for i, seq in enumerate(sequence):
    #    row = seq.split("\t")
    #    line = ""
    #    for r in row:
    #        if "ID" in r:
    #            line += r+"\t"
    #            continue
    #        temp = int(r[2:])
    #        line += "ST" + str(stcnt) + "\t"
    #        stcnt += 1
    #    sequence[i] = line

    for st_pre_post_num in st_pre_post_nums:
        for i,seq in enumerate(sequence):
            row = seq.split("\t")
            for j,target in enumerate(row):
                if target == st_pre_post_num[0]:
                    row[j] = st_pre_post_num[1]
            sequence[i] = "\t".join(row)

    for i,seq in enumerate(sequence):
        row = seq.split("\t")
        newrow = []
        for r in row:
            if "ST" in r and r in newrow:
                continue
            newrow.append(r)

        sequence[i] = "\t".join(newrow)
    # changed 2017_0330_wakabayashi_ここまで


    fo = open(out_directory+("stm_jotailist.tsv"),"w")
    for jl in jotailist:
        print(jl,file=fo)
    fo.close()

    fo = open(out_directory+("stm_idlist2.tsv"),"w")
    for tl in targetlist:
        print(tl,file=fo)
    fo.close()

    fo = open(out_directory+("stm_sequence2.tsv"),"w")
    for seq in sequence:
        print(seq,file=fo)
    fo.close()

    fo = open(out_directory+("stm_stlist2.tsv"),"w")
    for st in stlist:
        print(st,file=fo)
    fo.close()

    fo = open(out_directory+("stm_eventlist.tsv"),"w")
    for el in eventlist:
        print(el,file=fo)
    fo.close()

    fo = open(out_directory+("stm_jotaivalue.tsv"),"w")
    for jv in jotaivalue:
        print(jv,file=fo)
    fo.close()

if __name__ == '__main__':
    getjotaivalue(sys.argv[1],sys.argv[2],sys.argv[3])
