import argparse
from itertools import *

import os.path
import yaml
from colors import color

import ee.digikey as dk
from ee.digikey import SearchResponseTypes, DigikeyProduct
from ee.tools import mk_parents

parser = argparse.ArgumentParser(description="Download facts about parts from Digi-Key")

parser.add_argument("parts",
                    metavar="PART",
                    nargs="+",
                    help="The parts to download fact for")

parser.add_argument("--out",
                    required=True,
                    metavar="OUTPUT_DIRECTORY",
                    dest="out",
                    action="store",
                    help="A directory to store fact files")

parser.add_argument("--force",
                    dest="force",
                    action="store",
                    help="Always download fact even if there is a local file")

args = parser.parse_args()

digikey = dk.Digikey()
client = dk.DigikeyClient(digikey, on_download=lambda s: print(color(s, 'grey')))


def mpn_to_path(mpn):
    return "{}/{}.yaml".format(args.out, mpn)


def on_product(product: DigikeyProduct):
    y = product.to_yaml()

    filename = mpn_to_path(product.mpn)
    mk_parents(filename)
    with open(filename, "w") as f:
        yaml.dump(y, f, encoding="utf-8", allow_unicode=True)


for p in args.parts:
    print(color("Searching for {}".format(p), "white"))
    path = mpn_to_path(p)

    if os.path.isfile(path) and not args.force:
        continue

    response = client.search(p)

    if response.response_type == SearchResponseTypes.SINGLE:
        p = response.products[0]
        print(color("Direct match {}".format(p.mpn), "white"))
        on_product(p)
    elif response.response_type == SearchResponseTypes.MANY:
        hits = list(groupby(sorted(response.products), lambda p: p.mpn))

        if len(hits) == 1:
            (mpn, products) = hits[0]
            products = list(products)

            if len(products) == 1:
                print(color("Got many results, but they all point to the same part: {}".format(mpn), "white"))
                on_product(products[0])
                continue

        for k, g in hits:
            print(color("Got many results with many parts: {}: {}".format(k, list(g)), "white"))
            on_product(list(g)[0])
    elif response.response_type == SearchResponseTypes.TOO_MANY:
        print(color("Too many results ({}), select a category first".format(response.count), 'red'))
    elif response.response_type == SearchResponseTypes.NO_MATCHES:
        print(color("Part not found", "orange"))