# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from import_export import fields
from import_export import resources
from ralph.cmdb import models_ci
from ralph.discovery import models_device
from ralph.discovery import models_component
from ralph_assets import models_dc_assets
from ralph_assets import models_assets
from ralph_assets.licences.models import Licence


class BackOfficeAssetResource(resources.ModelResource):
    class Meta:
        fields = [
            'id',
            'barcode',
            'delivery_date',
            'deprecation_end_date',
            'deprecation_rate',
            'force_deprecation',
            'hostname',
            'invoice_date',
            'invoice_no',
            'loan_end_date',
            'model_id',
            'niw',
            'order_no',
            'price',
            'production_use_date',
            'production_year',
            'provider',
            'provider_order_date',
            'purchase_order',
            'request_date',
            'required_support',
            'sn',
            'source',
            'status',
            'task_url',
        ]
        model = models_assets.Asset

    def get_queryset(self):
        return self.Meta.model.objects.filter(
            type=models_assets.AssetType.back_office,
        )


class DataCenterAssetResource(resources.ModelResource):
    service_env = fields.Field()
    rack = fields.Field('rack', column_name='rack')

    rack = fields.Field('rack', column_name='rack')
    orientation = fields.Field('orientation', column_name='orientation')
    position = fields.Field('position', column_name='position')
    slot_no = fields.Field('slot_no', column_name='slot_no')

    def dehydrate_rack(self, asset):
        try:
            rack = asset.device_info.rack.id or ''
        except AttributeError:
            rack = ''
        return rack

    def dehydrate_orientation(self, asset):
        try:
            orientation = asset.device_info.orientation or ''
        except AttributeError:
            orientation = ''
        return orientation

    def dehydrate_position(self, asset):
        try:
            position = asset.device_info.position or ''
        except AttributeError:
            position = ''
        return position

    def dehydrate_slot_no(self, asset):
        try:
            slot_no = asset.device_info.slot_no
        except AttributeError:
            slot_no = ''
        return slot_no

    def dehydrate_barcode(self, asset):
        return asset.barcode or ''

    def dehydrate_sn(self, asset):
        return asset.sn or ''

    def dehydrate_hostname(self, asset):
        try:
            hostname = asset.device_info.ralph_device.name
        except AttributeError:
            hostname = None
        return hostname

    def dehydrate_service_env(self, asset):
        service_env = ""
        service = getattr(asset.service, 'name', '')
        device_environment = getattr(asset.device_environment, 'name', '')
        if service and device_environment:
            service_env = "{}|{}".format(service, device_environment)
        return service_env

    class Meta:
        fields = (
            # to be skipped
            'id',
            #    'asset_ptr': '',
            #    'baseobject_ptr': '',
            # to be dehydrated
            'service_env',
            # TODO:
            #    'configuration_path': '',
            # complicated:
            # TODO:
            #    'parent': '',
            'barcode',
            # TODO: m2m
            'connections',
            'created',
            'delivery_date',
            'deprecation_end_date',
            'deprecation_rate',
            'force_deprecation',
            'invoice_date',
            'invoice_no',
            'loan_end_date',
            'model',
            'modified',
            'niw',
            'order_no',
            'orientation',
            'position',
            'price',
            'production_use_date',
            'production_year',
            'provider',
            'provider_order_date',
            'purchase_order',
            'rack',
            'remarks',
            'request_date',
            'required_support',
            'slot_no',
            'slots',
            'sn',
            'source',
            'status',
            'task_url',
            'hostname',
        )
        model = models_assets.Asset

    def get_queryset(self):
        return self.Meta.model.objects.filter(
            type=models_assets.AssetType.data_center,
            part_info=None,
        )


class AssetModelResource(resources.ModelResource):
    class Meta:
        fields = (
            'id',
            'category',
            'cores_count',
            'height_of_device',
            'manufacturer',
            'power_consumption',
            'visualization_layout_back',
            'visualization_layout_front',
            'type',
            'created',
            'modified',
            'name',
        )
        model = models_assets.AssetModel


class ManufacturerResource(resources.ModelResource):
    class Meta:
        model = models_assets.AssetManufacturer


class CategoryResource(resources.ModelResource):
    id = fields.Field('slug', column_name='id')

    def dehydrate_parent(self, asset_category):
        return asset_category.parent.slug if asset_category.parent else ''

    class Meta:
        fields = (
            'created datetime',
            'created_by_id',
            'modified',
            'modified_by_id',
            'slug',
            'name',
            'code',
            'is_blade',
            'parent',
            # skip it
            # cache_version
            # level
            # lft
            # rght
            # tree_id
            # type
        )
        model = models_assets.AssetCategory


class ServiceEnvironmentResource(resources.ModelResource):
    service = fields.Field()
    environment = fields.Field()

    def dehydrate_service(self, ci_relation):
        return ci_relation.parent.id

    def dehydrate_environment(self, ci_relation):
        return ci_relation.child.id

    def get_queryset(self):
        return models_ci.CIRelation.objects.filter(
            type=models_ci.CI_RELATION_TYPES.CONTAINS,
            parent__in=models_device.ServiceCatalog.objects.all(),
            child__type=models_ci.CIType.objects.get(name='Environment'),
        )

    class Meta:
        fields = (
            'id',
            'service',
            'environment',
        )
        model = models_ci.CIRelation


class ServiceResource(resources.ModelResource):
    name = fields.Field(column_name='name')
    profit_center = fields.Field(column_name='profit_center')

    def dehydrate_name(self, service):
        return service.name

    def dehydrate_profit_center(self, service):
        profit_center = service.child.filter(
            parent__type=models_ci.CI_TYPES.PROFIT_CENTER,
        )
        assert len(profit_center) < 2, 'found many profit centers'
        if profit_center:
            profit_center_name = profit_center[0].parent.name
        else:
            profit_center_name = None
        return profit_center_name

    def get_queryset(self):
        return models_device.ServiceCatalog.objects.all()

    class Meta:
        fields = (
            'id',
            'name',
            'created',
            'modified',
            'profit_center',
            # TODO: no table in NG for now
            # 'cost_center': '',
        )
        model = models_ci.CIRelation


class RackResource(resources.ModelResource):
    class Meta:
        exclude = ('data_center', 'accessories', 'deprecated_ralph_rack',)
        model = models_dc_assets.Rack


class EnvironmentResource(resources.ModelResource):
    class Meta:
        fields = ('id', 'name', 'created', 'modified',)
        model = models_device.DeviceEnvironment


class GenericComponentResource(resources.ModelResource):
    asset = fields.Field()

    def dehydrate_model(self, component):
        try:
            model_name = component.model.name
        except AttributeError:
            model_name = ''
        return model_name

    def dehydrate_asset(self, component):
        try:
            sn = component.device.get_asset().sn
        except AttributeError:
            sn = ''
        return sn

    class Meta:
        model = models_component.GenericComponent


class LicenceResource(resources.ModelResource):
    class Meta:
        model = Licence
        fields = [
            'id', 'created', 'modified', 'manufacturer_id', 'licence_type_id',
            'software_category_id', 'number_bought', 'sn', 'niw', 'valid_thru',
            'order_no', 'price', 'accounting_id', 'invoice_date', 'provider',
            'invoice_no', 'remarks', 'license_details', 'licence_type',
            'software_category'
        ]

    def dehydrate_manufacturer(self, licence):
        return licence.manufacturer.name

    def dehydrate_licence_type(self, licence):
        return licence.licence_type.name

    def dehydrate_software_category(self, licence):
        return licence.software_category.name
