import numpy
import os


def readrcp(rcpfile):
    # tab depth used for dictionary nesting
    def getKeyDepth(key):
        counter = (len(key) - len(key.lstrip())) / 4
        return counter

    f = open(rcpfile, "rU")
    rcp = f.readlines()
    f.close()

    # make d[k, v] from lines of 'k: v', recurse function call if v is empty
    def readKeys(rcplines, depth=0):
        d = {}
        for i, cline in enumerate(rcplines):
            cdepth = getKeyDepth(cline)
            if cdepth != depth:
                next
            else:
                k = cline.split(":")[0].rstrip("\r\n")
                try:
                    v = cline.split(": ")[1].lstrip().rstrip("\r\n")
                except:
                    remaining_cdepths = [
                        l
                        for l, v in enumerate(
                            [getKeyDepth(line) for line in rcplines[i + 1 :]]
                        )
                        if v == cdepth
                    ]
                    if len(remaining_cdepths) == 0:
                        v = readKeys(rcplines[i + 1 :], depth=cdepth + 1)
                    else:
                        v = readKeys(
                            rcplines[i + 1 : i + remaining_cdepths[0] + 1],
                            depth=cdepth + 1,
                        )
                    pass
                d[k.lstrip()] = v
                if i == len(rcplines) | cdepth > getKeyDepth(rcplines[i + 1]):
                    return d
        return d

    return readKeys(rcp)


def myeval(c):
    if c == "None":
        c = None
    elif c == "nan" or c == "NaN":
        c = numpy.nan
    else:
        temp = c.lstrip("0")
        if (temp == "" or temp == ".") and "0" in c:
            c = 0
        else:
            c = eval(temp)
    return c


def readsingleplatemaptxt(p, returnfiducials=False, erroruifcn=None, lines=None):
    if lines is None:
        try:
            f = open(p, mode="r")
        except:
            if erroruifcn is None:
                return []
            p = erroruifcn("bad platemap path")
            if len(p) == 0:
                return []
            f = open(p, mode="r")

        ls = f.readlines()
        f.close()
    else:
        ls = lines
    if returnfiducials:
        s = ls[0].partition("=")[2].partition("mm")[0].strip()
        if (
            not "," in s[s.find("(") : s.find(")")]
        ):  # needed because sometimes x,y in fiducials is comma delim and sometimes not
            print("WARNING: commas inserted into fiducials line to adhere to format.")
            print(s)
            s = (
                s.replace("(   ", "(  ")
                .replace("(  ", "( ")
                .replace("( ", "(")
                .replace("   )", "  )")
                .replace(",  ", ",")
                .replace(", ", ",")
                .replace("  )", " )")
                .replace(" )", ")")
                .replace("   ", ",")
                .replace("  ", ",")
                .replace(" ", ",")
            )
            print(s)
        fid = eval("[%s]" % s)
        fid = numpy.array(fid)
    for count, l in enumerate(ls):
        if not l.startswith("%"):
            break
    keys = ls[count - 1][1:].split(",")
    keys = [(k.partition("(")[0]).strip() for k in keys]
    dlist = []
    for l in ls[count:]:
        sl = l.split(",")
        d = dict([(k, myeval(s.strip())) for k, s in zip(keys, sl)])
        dlist += [d]
    if not "sample_no" in keys:
        dlist = [dict(d, sample_no=d["Sample"]) for d in dlist]
    if returnfiducials:
        return dlist, fid
    return dlist
