import os
import configargparse

from ont_fast5_api import fast5_file, multi_fast5
from minFQ.minotourapi import MinotourAPI
from tqdm import tqdm

# TODO I don't think we use this, can we delete this file?

def main():
    parser = configargparse.ArgParser(
        description="minFQ: A program to analyse minION fastq files in real-time or post-run and monitor the activity of MinKNOW."
    )

    parser.add(
        "-w",
        "--watch-dir",
        type=str,
        required=True,
        default=None,
        help="The path to the folders containing fast5 reads to analyse - e.g. C:\\data\\minion\\downloads (for windows).",
        dest="watchdir",
    )

    parser.add(
        "-k",
        "--key",
        type=str,
        required=True,
        default=None,
        help="The api key for uploading data.",
        dest="api_key",
    )

    parser.add(
        "-p",
        "--port",
        type=int,
        # required=True,
        default=80,
        help="The port number for the local server.",
        dest="port_number",
    )

    parser.add(
        "-hn",
        "--hostname",
        type=str,
        required=True,
        default="127.0.0.1",
        help="The host name you are loading data too.",
        dest="host_name",
    )

    args = parser.parse_args()

    minION = set()
    flowcelldict = dict()
    rundict = dict()

    print("Searching for files in {}".format(os.path.abspath(args.watchdir)))
    last_seen = ""
    for root, subdirs, files in tqdm(os.walk(args.watchdir)):
        files.sort()
        for file in tqdm(files):
            if file.endswith("fast5"):
                if file.split("_read_")[0] != last_seen:
                    last_seen = file.split("_read_")[0]
                    try:
                        try:
                            myfile = fast5_file.Fast5File(os.path.join(root, file))

                        except:
                            mymultifile = multi_fast5.MultiFast5File(
                                os.path.join(root, file)
                            )
                            myid = mymultifile.get_read_ids()[0]
                            myfile = mymultifile.get_read(myid)
                        minIONid = myfile.get_tracking_id()["device_id"]
                        minION.add(minIONid)
                        flowcell = myfile.get_tracking_id()["flow_cell_id"]
                        if len(flowcell) < 1:
                            flowcell = input("Enter a flowcell name: ")
                        sample_id = myfile.get_tracking_id()["sample_id"]
                        run_id = myfile.get_tracking_id()["run_id"]
                        if sample_id not in flowcelldict.keys():
                            flowcelldict[sample_id] = dict()
                        if flowcell not in flowcelldict[sample_id].keys():
                            flowcelldict[sample_id][flowcell] = dict()
                        if run_id not in flowcelldict[sample_id][flowcell].keys():
                            flowcelldict[sample_id][flowcell][run_id] = dict()
                            flowcelldict[sample_id][flowcell][run_id][
                                "tracking_id"
                            ] = myfile.get_tracking_id()
                            flowcelldict[sample_id][flowcell][run_id][
                                "context_tags"
                            ] = myfile.get_context_tags()
                    except:
                        print("Non fast5file seen.")
    print("Adding new runs.")

    header = {
        "Authorization": "Token {}".format(args.api_key),
        "Content-Type": "application/json",
    }
    minotourapi = MinotourAPI(args.host_name, args.port_number, header)
    for minIONs in minION:
        minion = minotourapi.get_minion_by_name(minIONs)
        if not minion:
            minion = minotourapi.create_minion(minIONs)
        minion = minion
    for sample_id in tqdm(flowcelldict):
        for flowcellid in flowcelldict[sample_id].keys():
            flowcell = minotourapi.get_flowcell_by_name(flowcellid)
            if len(flowcell["data"]) == 0:
                create_flowcell = minotourapi.create_flowcell(flowcellid)
                flowcell = minotourapi.get_flowcell_by_name(flowcellid)
            for run_id in flowcelldict[sample_id][flowcellid]:
                run = minotourapi.get_run_by_runid(run_id)
                if not run:
                    """print (flowcell)"""
                    is_barcoded = False  # TODO do we known this info at this moment? This can be determined from run info.
                    has_fastq = True  # TODO do we known this info at this moment? This can be determined from run info
                    run = minotourapi.create_run(
                        sample_id,
                        run_id,
                        is_barcoded,
                        has_fastq,
                        flowcell["data"],
                        minion,
                        flowcelldict[sample_id][flowcellid][run_id]["tracking_id"][
                            "exp_start_time"
                        ],
                    )

                minion = minotourapi.get_minion_by_name(
                    flowcelldict[sample_id][flowcellid][run_id]["tracking_id"][
                        "device_id"
                    ]
                )

                try:
                    sample_rate = int(
                        str(
                            flowcelldict[sample_id][flowcellid][run_id]["context_tags"][
                                "sample_frequency"
                            ]
                        )
                    )
                except:
                    sample_rate = 0

                payload = {
                    "minION": str(minion["url"]),
                    "minKNOW_current_script": str(""),
                    "minKNOW_sample_name": str(sample_id),
                    "minKNOW_exp_script_purpose": str(
                        flowcelldict[sample_id][flowcellid][run_id]["tracking_id"][
                            "exp_script_purpose"
                        ]
                    ),
                    "minKNOW_flow_cell_id": flowcellid,
                    "minKNOW_run_name": str(""),
                    "run_id": str(run["url"]),
                    "minKNOW_version": str(
                        flowcelldict[sample_id][flowcellid][run_id]["tracking_id"][
                            "version"
                        ]
                    ),
                    "minKNOW_hash_run_id": str(run_id),
                    "minKNOW_script_run_id": str(""),
                    "minKNOW_real_sample_rate": sample_rate,
                    "minKNOW_asic_id": flowcelldict[sample_id][flowcellid][run_id][
                        "tracking_id"
                    ]["asic_id"],
                    "minKNOW_start_time": flowcelldict[sample_id][flowcellid][run_id][
                        "tracking_id"
                    ]["exp_start_time"],
                    "minKNOW_computer": str(
                        flowcelldict[sample_id][flowcellid][run_id]["tracking_id"][
                            "hostname"
                        ]
                    ),
                }
                try:
                    payload["flowcell_type"] = str(
                        flowcelldict[sample_id][flowcellid][run_id]["context_tags"][
                            "flowcell_type"
                        ]
                    )
                except:
                    payload["flowcell_type"] = "unknown"
                try:
                    payload["sequencing_kit"] = str(
                        flowcelldict[sample_id][flowcellid][run_id]["context_tags"][
                            "sequencing_kit"
                        ]
                    )
                except:
                    payload["sequencing_kit"] = "unknown"

                updateruninfo = minotourapi.update_minion_run_info(payload, run["id"])

    print("Metadata Uploaded to MinoTour.")
