import re


def generate_top_kmer_md_table(t_kmer_dic, g_kmer_dic,
                               top=5,
                               val_type="c"):
    """
    Given k-mer count dictionaries for genomic and transcript context set,
    generate a markdown table with top 5 k-mers (sorted by decending
    dictionary value).

    val_type:
    Specify type of stored dictionary value.
    c : count (count of k-mer)
    r : ratio (k-mer count / total k-mer count)
    p : percentage ( (k-mer count / total k-mer count) * 100)

    """
    assert t_kmer_dic, "given dictionary t_kmer_dic empty"
    assert g_kmer_dic, "given dictionary g_kmer_dic empty"
    assert re.search("^[c|p|r]$", val_type), "invalid val_type given"
    # Get size of k.
    k = 0
    for kmer in t_kmer_dic:
        k = len(kmer)
        break
    # Expected kmer number.
    exp_kmer_nr = pow(4,k)
    t_kmer_nr = 0
    g_kmer_nr = 0
    for kmer in t_kmer_dic:
        kc = t_kmer_dic[kmer]
        if kc:
            t_kmer_nr += 1
    for kmer in g_kmer_dic:
        kc = g_kmer_dic[kmer]
        if kc:
            g_kmer_nr += 1
    t_kmer_perc = "%.2f " %((t_kmer_nr / exp_kmer_nr) * 100) + " %"
    g_kmer_perc = "%.2f " %((g_kmer_nr / exp_kmer_nr) * 100) + " %"
    # Adjust decimal places based on k-mer size.
    dc_p = 2
    dc_r = 4
    if k > 3:
        for i in range(k-3):
            dc_p += 1
            dc_r += 1
    dc_p_str = "%."+str(dc_p)+"f"
    dc_r_str = "%."+str(dc_r)+"f"
    add_ch = ""
    if val_type == "p":
        add_ch = " %"
        # Format percentage to two decimal places.
        for kmer in t_kmer_dic:
            new_v = dc_p_str % t_kmer_dic[kmer]
            t_kmer_dic[kmer] = new_v
        for kmer in g_kmer_dic:
            new_v = dc_p_str % g_kmer_dic[kmer]
            g_kmer_dic[kmer] = new_v
    elif val_type == "r":
        # Format percentage to four decimal places.
        for kmer in t_kmer_dic:
            new_v = dc_r_str % t_kmer_dic[kmer]
            t_kmer_dic[kmer] = new_v
        for kmer in g_kmer_dic:
            new_v = dc_r_str % g_kmer_dic[kmer]
            g_kmer_dic[kmer] = new_v

    # Get top j k-mers.
    i = 0
    t_topk_list = []

    for kmer, v in sorted(t_kmer_dic.items(), key=lambda item: item[1], reverse=True):
        i += 1
        if i > top:
            break
        t_topk_list.append(kmer)
    i = 0
    g_topk_list = []
    for kmer, v in sorted(g_kmer_dic.items(), key=lambda item: item[1], reverse=True):
        i += 1
        if i > top:
            break
        g_topk_list.append(kmer)

    # Generate markdown table.
    mdtable = "| Rank | &nbsp; &nbsp; Transcript context &nbsp; &nbsp; | &nbsp; &nbsp; Genomic context &nbsp; &nbsp;|\n"
    mdtable += "| :-: | :-: | :-: |\n"
    for i in range(top):
        t_kmer = t_topk_list[i]
        g_kmer = g_topk_list[i]
        pos = i + 1
        mdtable += "| %i | %s (%s%s) | %s (%s%s) |\n" %(pos, t_kmer, str(t_kmer_dic[t_kmer]), add_ch, g_kmer, str(g_kmer_dic[g_kmer]), add_ch)

    mdtable += "| ... | &nbsp; | &nbsp; |\n"
    mdtable += "| # distinct k-mers | %i (%s) | %i (%s) |\n" %(t_kmer_nr, t_kmer_perc, g_kmer_nr, g_kmer_perc)

    # Return markdown table.
    return mdtable