from nodeconductor.cost_tracking import CostTrackingRegister, CostTrackingStrategy, ConsumableItem

from . import models, ApplicationTypes, OsTypes, SupportTypes, PriceItemTypes


class InstanceStrategy(CostTrackingStrategy):
    resource_class = models.Instance

    class Types(object):
        FLAVOR = PriceItemTypes.FLAVOR
        LICENSE_APPLICATION = PriceItemTypes.LICENSE_APPLICATION
        LICENSE_OS = PriceItemTypes.LICENSE_OS
        SUPPORT = PriceItemTypes.SUPPORT

    @classmethod
    def get_consumable_items(cls):
        for os, name in OsTypes.CHOICES:
            yield ConsumableItem(item_type=cls.Types.LICENSE_OS, key=os, name='OS: %s' % os)

        for key, name in ApplicationTypes.CHOICES:
            yield ConsumableItem(
                item_type=cls.Types.LICENSE_APPLICATION, key=key, name='Application: %s' % name)

        for key, name in SupportTypes.CHOICES:
            yield ConsumableItem(item_type=cls.Types.SUPPORT, key=key, name='Support: %s' % name)

        for flavor_name in set(models.Flavor.objects.all().values_list('name', flat=True)):
            yield ConsumableItem(item_type=cls.Types.FLAVOR, key=flavor_name, name='Flavor: %s' % flavor_name)

    @classmethod
    def get_configuration(cls, instance):
        States = models.Instance.States
        tags = [t.name for t in instance.tags.all()]

        consumables = {}
        for type in (cls.Types.LICENSE_APPLICATION, cls.Types.LICENSE_OS, cls.Types.SUPPORT):
            try:
                key = [t.split(':')[1] for t in tags if t.startswith('%s:' % type)][0]
            except IndexError:
                continue
            consumables[ConsumableItem(item_type=type, key=key)] = 1

        if instance.state == States.ONLINE:
            consumables[ConsumableItem(item_type=cls.Types.FLAVOR, key=instance.flavor_name)] = 1
        return consumables


CostTrackingRegister.register_strategy(InstanceStrategy)


class VolumeStrategy(CostTrackingStrategy):
    resource_class = models.Volume

    class Types(object):
        STORAGE = PriceItemTypes.STORAGE

    @classmethod
    def get_consumable_items(cls):
        return [ConsumableItem(item_type=cls.Types.STORAGE, key='1 GB', name='1 GB of storage', units='GB')]

    @classmethod
    def get_configuration(cls, volume):
        return {ConsumableItem(item_type=cls.Types.STORAGE, key='1 GB'): float(volume.size) / 1024}


CostTrackingRegister.register_strategy(VolumeStrategy)


class SnapshotStrategy(CostTrackingStrategy):
    resource_class = models.Snapshot

    class Types(object):
        STORAGE = PriceItemTypes.STORAGE

    @classmethod
    def get_consumable_items(cls):
        return [ConsumableItem(item_type=cls.Types.STORAGE, key='1 GB', name='1 GB of storage', units='GB')]

    @classmethod
    def get_configuration(cls, snapshot):
        return {ConsumableItem(item_type=cls.Types.STORAGE, key='1 GB'): float(snapshot.size) / 1024}


CostTrackingRegister.register_strategy(SnapshotStrategy)

@@ -2066,32 +2066,82 @@
 mTypes.STORAGE%0A%0A
+    class Keys(object):%0A        STORAGE = '1 GB'%0A%0A
     @classmethod
@@ -2232,38 +2232,48 @@
 es.STORAGE, key=
-'1 GB'
+cls.Keys.STORAGE
 , name='1 GB of 
@@ -2409,38 +2409,48 @@
 es.STORAGE, key=
-'1 GB'
+cls.Keys.STORAGE
 ): float(volume.
@@ -2669,24 +2669,74 @@
 es.STORAGE%0A%0A
+    class Keys(object):%0A        STORAGE = '1 GB'%0A%0A
     @classme
@@ -2839,22 +2839,32 @@
 GE, key=
-'1 GB'
+cls.Keys.STORAGE
 , name='
@@ -3018,22 +3018,32 @@
 GE, key=
-'1 GB'
+cls.Keys.STORAGE
 ): float

Store storage key as constant