from django.test import TestCase
from django.core.exceptions import ValidationError

from ..models import Service, Cost, CostUse, Document


class AbstractUseTests(TestCase):
    """ Testing AbstractUseTests through CostUse
    """
    def setUp(self):
        self.doc = Document.objects.create(name='budget')
        self.hosting_service = Service.objects.create(
            name='Physical hosting', document=self.doc)
        self.mailbox_service = Service.objects.create(
            name='Mailbox', document=self.doc)

        self.electricity_cost = Cost.objects.create(
            name='electricity',
            price=10,
            document=self.doc,
            capacity_unit='A',
            total_capacity=4,
        )

    def test_can_add_service_share(self):
        use = CostUse(
            service=self.hosting_service,
            resource=self.electricity_cost,
            share=0.4)

        use.full_clean()
        use.save()

    def test_can_add_service_share_with_custom_unity(self):
        use = CostUse(
            service=self.hosting_service,
            resource=self.electricity_cost,
            share=2)  # means 2 Amps

        self.hosting_service.subscriptions_count = 2
        self.hosting_service.save()

        use.full_clean()
        use.save()

        self.assertEqual(use.share, 2.0)
        self.assertEqual(use.real_share(), 4.0)
        self.assertEqual(use.cost_share(), 10)
        self.assertEqual(use.unit_cost_share(), 5)

    def test_cannot_add_excess_share_one(self):
        use = CostUse(
            service=self.hosting_service,
            resource=self.electricity_cost,
            share=40.1)

        with self.assertRaises(ValidationError):
            use.full_clean()
            use.save()

    def test_add_several_service_share(self):
        u1 = CostUse(
            service=self.hosting_service,
            resource=self.electricity_cost,
            share=0.4)

        u1.full_clean()
        u1.save()

        u2 = CostUse(
            service=self.mailbox_service,
            resource=self.electricity_cost,
            share=0.6)

        u2.full_clean()
        u2.save()

    def test_add_several_service_share_excessive_sum(self):
        u1 = CostUse(
            service=self.hosting_service,
            resource=self.electricity_cost,
            share=3)

        u1.full_clean()
        u1.save()

        u2 = CostUse(
            service=self.mailbox_service,
            resource=self.electricity_cost,
            share=1.1)

        # Would be 4.1 out of 4 amp...

        with self.assertRaises(ValidationError):
            u2.full_clean()
            u2.save()

    def test_modify_service_share_no_error(self):
        u1 = CostUse(
            service=self.hosting_service,
            resource=self.electricity_cost,
            share=1)

        u1.full_clean()
        u1.save()
        u1.full_clean()
        u1.save()

    def test_real_shares(self):
        u1 = CostUse.objects.create(
            service=self.hosting_service,
            resource=self.electricity_cost,
            share=1.6)
        u2 = CostUse.objects.create(
            service=self.hosting_service,
            resource=self.electricity_cost,
            share=0.6)

        self.assertEqual(u1.real_share() + u2.real_share(), 4)
        self.assertEqual(u1.share/u2.share, u1.real_share()/u2.real_share())

    def test_unit_value_share(self):
        self.mailbox_service.subscriptions_count = 2
        self.mailbox_service.share = 0.5
        self.hosting_service.save()

        self.hosting_service.subscriptions_count = 1
        self.hosting_service.share = 0.5
        self.hosting_service.save()

        mailbox_use = CostUse.objects.create(
            service=self.mailbox_service,
            resource=self.electricity_cost,
            share=2)

        hosting_use = CostUse.objects.create(
            service=self.hosting_service,
            resource=self.electricity_cost,
            share=2)

        self.assertEqual(mailbox_use.value_share(), 5)
        self.assertEqual(mailbox_use.unit_value_share(), 2.5)

        self.assertEqual(hosting_use.value_share(), 5)
        self.assertEqual(hosting_use.unit_value_share(), 5)

    def test_used(self):
        CostUse.objects.create(
            service=self.mailbox_service,
            resource=self.electricity_cost,
            share=0.5)

        self.assertEqual(self.electricity_cost.used(), 0.5)
        self.assertEqual(self.electricity_cost.unused(), 3.5)