import cardsharp as cs
import os
import time
from collections import defaultdict

__all__ = ['txt_to_excel','excel_to_txt']

def txt_to_excel(state):
    
    metas = [':null_predict:',':key_predicate:',':value_predicate:',':overwrite:',':null_predicate:',':missing:',':unknown:',':lookup:',':vars:',':keys:',':skip_missing:',':skip_unknown:',':remove_key:',':transform_results:',':key:',':force_unknown:']
    crosswalks = defaultdict(list)
    for (path,dirs,files) in os.walk("../process_rules_2/sentence/snttextx/" + str(state)):
        for crosswalk in files:
            if ".txt" in crosswalk: crosswalks[str(path)].append(str(crosswalk).split("/")[-1])
    for folder in crosswalks.keys():
        output = str(folder).replace("../","")
        try: os.unlink("\\".join([output,"crosswalks.xls"]))
        except: pass
        if not os.path.exists(output): os.makedirs(output)
        for crosswalk in crosswalks[folder]:
            print str("/".join([folder,crosswalk]))
            input = open("/".join([folder,crosswalk]),"r")
            inputlines = input.readlines()
            metadata = cs.Dataset(["field","value1","value2","value3","value4","value5"])
            rulefields = ["ruletype","key"]
            for line in inputlines:
                data = str(line).split("\t")
                if str(data[0])==":vars:":
                    for var in data[1].split("|"): rulefields.append(str(var))
                    break
            if len(rulefields) < 3: rulefields.append("value")
            rulefields.append("priority")
            rules = cs.Dataset(rulefields)
            for line in reversed(inputlines):
                if str(line)!="\n":
                    data = str(line).split("\t")
                    if str(data[0]) in metas:
                        field = str(data[0])
                        values = []
                        for value in data[1:]: values.append(str(value))
                        while len(values) < 5: values.append("")
                        #print "Metadata: " + str(field) + ", values: " + str(values)
                        #print str([str(field),str(values[0]),str(values[1]),str(values[2]),str(values[3]),str(values[4])])
                        metadata.add_row([str(field),str(values[0]),str(values[1]),str(values[2]),str(values[3]),str(values[4])])
                    else:
                        if ":re:" in str(data[0]) or ":all:" in str(data[0]):
                            rule = ":".join(str(data[0]).split(":")[:3])
                            rule += ":"
                            initial = ":".join(str(data[0]).split(":")[3:])
                        else:
                            rule = ""
                            initial = str(data[0])
                        try: priority = str(data[2])
                        except: priority = ""
                        result = str(data[1])
                        row = [str(rule),str(initial)]
                        for var in result.split("|"): row.append(str(var))
                        row.append(str(priority))
                        rules.add_row(row)
                        #print "Rule: " + str(rule) + ", initial: " + str(initial) + ", result: " + str(result) + ", priority: " + str(priority)
            sheetname = str(crosswalk).replace("crosswalk_","").replace(".txt","")
            #print str(sheetname)
            
            rules.save(source="\\".join([output,"crosswalks.xls"]),format='excel',overwrite=True,dataset="_".join([sheetname,"rules"]))
            cs.wait()
            sleep = len(rules.rows)*.0001
            time.sleep(sleep)
            metadata.save(source="\\".join([output,"crosswalks.xls"]),format='excel',overwrite=True,dataset="_".join([sheetname,"metadata"]))
            cs.wait()
            
def excel_to_txt(state):
    
    sheets =defaultdict(list)
    for (path,dirs,files) in os.walk("../process_rules_2/sentence/snttextx/" + str(state)):
        for crosswalk in files: 
            if ".txt" in crosswalk: 
                sheets[str(path).split("/")[-1]].append(str(crosswalk).replace("crosswalk_","").replace(".txt",""))      
                try: os.unlink("/".join([str(path).replace("../",""),str(crosswalk)]))
                except: pass
    metas = [':null_predict:',':key_predicate:',':value_predicate:',':overwrite:',':null_predicate:',':missing:',':unknown:',':lookup:',':vars:',':keys:',':skip_missing:',':skip_unknown:',':remove_key:',':transform_results:',':key:',':force_unknown:']
    crosswalks =defaultdict(list)
    for (path,dirs,files) in os.walk("process_rules_2\\sentence\\snttextx\\" + str(state)):
        for crosswalk in files: 
            if ".xls" in crosswalk: crosswalks[str(path)].append(crosswalk)
    for folder in crosswalks.keys():
        outputpath = str(folder)
        if not os.path.exists(outputpath): os.makedirs(outputpath)
        for crosswalk in crosswalks[folder]:
            input = str("\\".join([folder,crosswalk]))
            print str(input)
            state = str(folder).split("\\")[3]
            metadatasheets = ["_".join([sheet,"metadata"]) for sheet in sheets[state]]
            rulesheets = ["_".join([sheet,"rules"]) for sheet in sheets[state]]
            try: 
                for sheet in metadatasheets:
                    sheetname = "".join([outputpath,"\\crosswalk_",sheet.replace("_metadata",""),".txt"])
                    output = open(sheetname,"a")
                    metadata = cs.load("/".join([folder,crosswalk]),dataset=str(sheet))
                    columns = [var.name for var in metadata.variables]
                    for row in metadata: 
                        row = str("\t".join([str(row[str(column)]) for column in columns if str(row[str(column)]) != "None"])).replace("\n","")
                        output.write(row+"\n")
                    output.close()
            except: "No metadata found"
            try: 
                for sheet in rulesheets:
                    sheetname = "".join([outputpath,"\\crosswalk_",sheet.replace("_rules",""),".txt"])
                    output = open(sheetname,"a")
                    rules = cs.load("/".join([folder,crosswalk]),dataset=str(sheet))
                    columns = [var.name for var in rules.variables]
                    for row in rules:
                        fields = []
                        for column in columns: 
                            if str(row[str(column)]) != "None": fields.append(str(row[str(column)]))
                            else: fields.append("")
                        #if ":re:" not in str(fields[0]) or ":all:" not in str(fields[0]):
                            #output.write("\t".join([fields[0],"|".join([str(field) for field in fields[1:-1]]),fields[-1]]))
                        #else:
                        #print "\t".join(["".join([fields[0],fields[1]]),"|".join([str(field) for field in fields[2:-1]]),fields[-1]])
                        row = str("\t".join(["".join([fields[0],fields[1]]),"|".join([str(field) for field in fields[2:-1]]),fields[-1]])).replace("\n","")
                        output.write(row+"\n")
                    output.close()
            except: "No rules found"
                
def validate(state):
    originals = []
    tests = []
    for (path,dirs,files) in os.walk("../process_rules_2/sentence/snttextx/" + str(state)):
        for crosswalk in files: 
            if ".txt" in crosswalk: 
                originals.append(str(path) + "/" + str(crosswalk))
                tests.append(str(path).replace("../","")+"/"+str(crosswalk))
    output = open("errors.txt","w")
    for i in range(0,len(originals)):
        originalfile = open(originals[i],"r")
        original = originalfile.readlines()
        testfile = open(tests[i],"r")
        test = testfile.readlines()
        #if len(original)==len(test):
        for j in range(0,len(original)):
            try: 
                if str(original[j]).replace("\n","").strip() not in str(test[j]).replace("\n","") and str(original[j])!="" and str(test[j])!="": 
                    output.write("Error: " + str(originals[i]) + " file, line " + str(j+1) + "\n")
            except: print "Could not read line " + str(j)
        #else: output.write("Error: " + str(tests[i]) + " files not the same length\n")
    output.close()
    