import io
import csv
import requests
from django.db import transaction
from django.core.files.images import ImageFile
from ..models import ComponentParameter, ComponentType, Manufacturer, Component, \
                    DistributorNum, Stock, Storage, Distributor, Package, ComponentParameterType

def _stock_component(component, storage_uuid, substorage_path, amount, lot, watermark):

    if not amount or not any([storage_uuid, substorage_path]):
        return None

    storage = Storage.from_path(substorage_path, storage_uuid)

    stock = Stock.objects.create(component=component,
                                 storage=storage,
                                 amount=amount,
                                 lot=lot,
                                 watermark=watermark)
    return stock

def _set_additional_parameters(component, type, value):

    if type.startswith('param:'):
        type = type[6:]
        param_type = ComponentParameterType.objects.get(parameter_name=type)

        param = ComponentParameter.objects.create(component=component,
                                                  parameter_type=param_type)
        if param_type.parameter_type == 'F':
            param.text_value = value
        else:
            param.value = float(value)
        param.save()

        return param

    elif type.startswith('distri:'):
        distri_name = type[7:]
        distri = Distributor.objects.get(name=distri_name)

        distri_num = DistributorNum.objects.create(component=component,
                                                   distributor=distri,
                                                   distributor_part_number=value)
        return distri_num

def import_components_from_csv(csv_file):
    """
    Imports components from a csv file containing the component model fields as
    well as storage information in the heading.

    Parameters can be set by param:<parameter name>, distri numbers by
    distri:<distri name>.
    """

    with transaction.atomic():

        # simulate a text-file for the csv lib
        with io.TextIOWrapper(csv_file, encoding='utf8') as csv_text_file:
            rows = csv.DictReader(csv_text_file, delimiter=";")

            for data in rows:

                image = None
                image_url = data.pop('image_url')
                if image_url:
                    response = requests.get(image_url)
                    image_content = response.content
                    image_file = io.BytesIO(image_content)
                    image = ImageFile(image_file, 'downloaded_file')

                manufacturer = None
                manufacturer_name = data.pop('manufacturer')
                if manufacturer_name:
                    manufacturer = Manufacturer.objects.get(name=manufacturer_name)

                component_type = None
                component_type_name = data.pop('component_type')
                if component_type_name:
                    component_type = ComponentType.objects.get(class_name=component_type_name)

                distributor = None
                pref_distri = data.pop('pref_distri')
                if pref_distri:
                    distributor = Distributor.objects.get(name=pref_distri)

                package = None
                package_name = data.pop('package')
                if package_name:
                    package = Package.objects.get(name=package_name)

                comp = Component.objects.create(name=data.pop('name'),
                                                manufacturer=manufacturer,
                                                component_type=component_type,
                                                pref_distri=distributor,
                                                description=data.pop('description'),
                                                datasheet_link=data.pop('datasheet_link'),
                                                package=package,
                                                image=image)

                _stock_component(comp,
                                 data.pop('storage_uuid'),
                                 data.pop('substorage_path'),
                                 data.pop('amount'),
                                 data.pop('lot'),
                                 data.pop('watermark'))

                for key, value in data.items():
                    _set_additional_parameters(comp, key, value)
