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

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

# ファイル名: split_funcs.py
# 機能: Excel上でユーザが選択したソースファイルの処理・条件式を関数ごとに分割する．
#	split_funcs.py以降のモジュールは分割された各関数における処理・条件式を対象に実行する．
# 関数: make_dir, allocateID, split_funcs
# 著者名: 山本椋太，若林丈紘

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

import re
import os
import shutil
import sys

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

# 関数名: make_dir
# 機能: 指定された名称のディレクトリを作成する．
# 引数
#   dir_path: 作成するディレクトリの名称

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

def make_dir(dir_path):
    if os.path.isdir(dir_path)==True:
        shutil.rmtree(dir_path)
    os.mkdir(dir_path)


# argument : idlist,sequenceの各行
# return   : ID,STが1から割り振られたidlist,sequenceの各行

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

# 関数名: allocateID
# 機能: ID, STの番号を割り当て直す
# 引数
#   ld_lines: 条件文もしくは関数名の行
#   sq_lines: それ以外の行

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

def allocateID(id_lines,sq_lines):

    idcnt = 1
    for i,id_line in enumerate(id_lines):
        temp = id_line.split("\t",1)
        id = temp[0]
        rest = temp[1]
        regep = id+"(\\t|\\n|$)"

        for j,seq in enumerate(sq_lines):
            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","")
            sq_lines[j] = result
            id_lines[j] = re.sub(regep,"ID"+str(idcnt)+"\t",id_lines[j])

        idcnt += 1

    stcnt = 1
    for i, seq in enumerate(sq_lines):
        row = seq.split("\t")
        line = ""
        for r in row:
            if "ID" in r:
                line += r+"\t"
                continue
            line += "ST" + str(stcnt) + "\t"
            stcnt += 1
        sq_lines[i] = line

    return (id_lines,sq_lines)

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

# 関数名: split_funcs
# 機能: 対象Cファイルの条件式，処理をまとめたファイルを関数ごとに分割する．
# 引数
#   directory: 解析対象のファイルに関する情報がまとめられたディレクトリ

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

def split_funcs(directory):

    print("\n===============")
    print("= split_funcs =")
    print("directory: ",directory)
    print("===============\n")

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

    # 関数: split_funcs
    # 機能： 対象Cファイルの条件式，処理をまとめたファイルを関数ごとに分割する


    # INPUT ： idlist2.tsv, stlist.tsv, sequence6.tsv
    # OUTPUT: idlist2-1.tsv, stlist2.tsv, sequence6-1.tsv
    #         idlist2-2.tsv, sequence6-2.tsv
    # RETURN: func_dic [dict型]

    # INPUTの入力元: temp/
    # OUTPUTの出力先: temp/FUNCTION/ (FUNCTIONは任意の関数名)

    # idlist2.tsv   : 通し番号(ID***)が割り当てられた条件式の一覧
    # stlist.tsv    : 通し番号（ST***)が割り当てられた処理の一覧
    # sequence6.tsv : 条件式（ID)と，その制御構造に内包されるID，STの一覧

    # idlist2-1.tsv   : idlist2.tsvを関数別に分割したファイル
    # stlist2.tsv     : stlist.tsvを関数別に分割したファイル
    # sequence6-1.tsv : sequence6.tsvを関数別に分割したファイル

    # idlist2-2.tsv   : idlist2-1.tsvのIDを1から再割り当てしたファイル
    # sequence6-2.tsv : sequence6-1.tsvのID,STを再割り当てしたファイル

    # func_dic : idlist2.tsvに記載されている関数名が
    #            上から順番に格納された辞書オブジェクト
    #            {通し番号:関数名}

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

    # INPUTファイルの読み込み
    out_directory = "temp/" + directory + "/"

    rfile = out_directory + "idlist2.tsv"
    fi = open(rfile)
    id_lines = fi.readlines()
    fi.close()

    rfile = out_directory + "stlist.tsv"
    fi = open(rfile)
    st_lines = fi.readlines()
    fi.close()

    rfile = out_directory + "sequence6.tsv"
    fi = open(rfile,"r")
    sq_lines = fi.read()[:-1].split("\n")
    fi.close()


    # 関数名のディレクトリを作成し，
    # idlist2.tsvを関数ごとに分割してディレクトリに出力する
    funcids = []
    funcnames = []

    for i,id_line in enumerate(id_lines):
        temp = id_line.split("\t")
        id = temp[0]
        code = temp[1]
        nest = int(temp[2])
        if nest == 0:
            funcids.append(id)
            funcnames.append(code)
            dir_path = out_directory + code + "/"
            make_dir(dir_path)
            fo_id = open(dir_path +"idlist2_1.tsv",'w')

        print (id_line,file=fo_id,end="")

        if i != len(id_lines)-1:
            next_nest = int(id_lines[i+1].split("\t")[2])
            if next_nest == 0:
                fo_id.close()
    fo_id.close()


    # sequence6.tsv, stlist.tsvを
    # 関数ごとに分割してディレクトリに出力する
    funccnt = 1
    for i,sq_line in enumerate(sq_lines):
        temp = sq_line.split("\t",1)
        target_id = temp[0]
        rest_ids = temp[1]

        if target_id == funcids[funccnt-1]:
            funcname = funcnames[funccnt-1]
            dir_path = out_directory + funcname + "/"
            fo_sq = open(dir_path +"sequence6_1.tsv",'w')
            fo_st = open(dir_path +"stlist2.tsv",'w')

        print (sq_line + "\n" ,file=fo_sq,end="")
        temp = rest_ids.split("\t")
        for t in temp:
            if "ST" in t:
                stnum = int(t[2:])
                st_line = st_lines[stnum-1]
                print (st_line,file=fo_st,end="")

        if funccnt != len(funcids):
            next_target_id = sq_lines[i+1].split("\t")[0]
            if next_target_id == funcids[funccnt]:
                funccnt += 1
                fo_sq.close()
                fo_st.close()

    fo_sq.close()
    fo_st.close()


    # ID, STの番号を割り当て直す
    for funcname in funcnames:
        dir_path = out_directory + funcname + "/"

        rfile = dir_path + "idlist2_1.tsv"
        fi = open(rfile)
        id_lines = fi.readlines()
        fi.close()

        rfile = dir_path + "sequence6_1.tsv"
        fi = open(rfile,"r")
        sq_lines = fi.read()[:-1].split("\n")
        fi.close()

        fo_id = open(dir_path + "idlist2_2.tsv",'w')
        fo_sq = open(dir_path + "sequence6_2.tsv",'w')

        newid_lines, newsq_lines =\
            allocateID(id_lines,sq_lines)

        for newid_line in newid_lines:
            print (newid_line,file=fo_id,end="")

        for newsq_line in newsq_lines:
            print (newsq_line + "\n" ,file=fo_sq,end="")

        fo_id.close()
        fo_sq.close()

    # senni.py(split_funcs.pyの呼び出し元)に
    # ｛通し番号：関数名｝の辞書型を返す
    func_dic = {}
    for i,funcname in enumerate(funcnames):
        func_dic.update({i:funcname})
    return func_dic

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