import base64

from rich.markdown import Markdown
from rich.table import Table

from vdb.lib.cve_model import CVE

NEWLINE = "\n"


def add_table_row(table: Table, res: dict, added_row_keys: dict):
    # matched_by is the purl or cpe string
    row_key = f"""{res["matched_by"]}|{res.get("source_data_hash")}"""
    # Filter duplicate rows from getting printed
    if added_row_keys.get(row_key):
        return
    source_data: CVE = res.get("source_data")
    fix_version = res.get("fix_version", "")
    descriptions = []
    cna_container = source_data.root.containers.cna
    affected_functions = set()
    affected_modules = set()
    if cna_container and cna_container.descriptions and cna_container.descriptions.root:
        for adesc in cna_container.descriptions.root:
            description = (
                "\n".join(
                    [
                        base64.b64decode(sm.value).decode("utf-8")
                        for sm in adesc.supportingMedia
                    ]
                )
                if adesc.supportingMedia
                else adesc.value
            )
            description = description.replace("\\n", "\n").replace("\\t", "  ")
            descriptions.append(description)
    if cna_container.affected and cna_container.affected.root:
        for each_affected in cna_container.affected.root:
            if each_affected.programRoutines:
                affected_functions |= {r.name for r in each_affected.programRoutines}
            if each_affected.modules:
                affected_modules |= {m.root for m in each_affected.modules}
    affected_functions = list(affected_functions)
    affected_modules = list(affected_modules)
    affects = ""
    if affected_functions:
        affects = f"## Functions\n- {(NEWLINE + '- ').join(affected_functions)}"
    if affected_modules:
        affects = f"{affects}\n## Modules\n- {(NEWLINE + '- ').join(affected_modules)}"
    matched_by_str = f'{res["matched_by"]}\n{res.get("purl_prefix")}' if not res["matched_by"].startswith("pkg:") else res["matched_by"] 
    table.add_row(
        res.get("cve_id"),
        matched_by_str,
        fix_version,
        Markdown("\n".join(descriptions), justify="left", hyperlinks=True),
        Markdown(affects, justify="left"),
    )
    added_row_keys[row_key] = True
