from cosmic.base import *
from cosmic.common import *
from cosmic.cosmicLog import CosmicLog
from cosmic.cosmicTestCase import cosmicTestCase


class TestIpExclusionList(cosmicTestCase):

    @classmethod
    def setUpClass(cls):
        cls.logger = CosmicLog(CosmicLog.LOGGER_TEST).get_logger()

        cls.test_client = super(TestIpExclusionList, cls).getClsTestClient()
        cls.api_client = cls.test_client.getApiClient()
        cls.test_data = cls.test_client.getParsedTestDataConfig()

        cls.class_cleanup = []

    @classmethod
    def tearDownClass(cls):

        try:
            cleanup_resources(cls.api_client, cls.class_cleanup, cls.logger)

        except Exception as e:
            raise Exception("Exception: %s" % e)

    def setUp(self):

        self.method_cleanup = []

    def tearDown(self):

        try:
            cleanup_resources(self.api_client, self.method_cleanup, self.logger)

        except Exception as e:
            raise Exception("Exception: %s" % e)

    @attr(tags=['advanced'])
    def test_01(self):

        self.setup_infra(redundant=False)
        self.setup_new_network()
        #
        # Deploy and test new VM
        #
        self.vm2 = self.deploy_new_vm('vm2')
        self._test_vm(self.vm2, '10.1.2.6')
        #
        # Try to deploy new VM without free IPs
        # Test failure
        #
        self.vm3 = self.deploy_new_vm('vm3')
        self._test_deploy_new_vm_failed(self.vm3)
        #
        # Update exlcluded IPs range
        # Deploy and test new VM
        #
        self.expand_free_ips()
        self.vm3 = self.deploy_new_vm('vm3')
        self._test_vm(self.vm3, '10.1.2.5')

    @classmethod
    def setup_infra(cls, redundant=False):

        if len(cls.class_cleanup) > 0:
            cleanup_resources(cls.api_client, cls.class_cleanup, cls.logger)
            cls.class_cleanup = []

        cls.zone = get_zone(cls.api_client, cls.test_client.getZoneForTests())
        cls.logger.debug("Zone '%s' selected" % cls.zone.name)

        cls.domain = get_domain(cls.api_client)
        cls.logger.debug("Domain '%s' selected" % cls.domain.name)

        cls.template = get_template(
            cls.api_client,
            cls.zone.id)
        cls.logger.debug("Template '%s' selected" % cls.template.name)

        cls.account = Account.create(
            cls.api_client,
            cls.test_data['account'],
            admin=True,
            domainid=cls.domain.id)

        cls.class_cleanup += [cls.account]
        cls.logger.debug("Account '%s' created", cls.account.name)

        cls.vpc_offering = get_default_redundant_vpc_offering(cls.api_client) if redundant else get_default_vpc_offering(cls.api_client)
        cls.logger.debug("VPC Offering '%s' selected", cls.vpc_offering.name)

        cls.network_offering = get_default_network_offering(cls.api_client)
        cls.logger.debug("Network Offering '%s' selected", cls.network_offering.name)

        cls.virtual_machine_offering = get_default_virtual_machine_offering(cls.api_client)
        cls.logger.debug("Virtual Machine Offering '%s' selected", cls.virtual_machine_offering.name)

        cls.default_allow_acl = get_network_acl(cls.api_client, 'default_allow')
        cls.logger.debug("ACL '%s' selected", cls.default_allow_acl.name)

        cls.default_deny_acl = get_network_acl(cls.api_client, 'default_deny')
        cls.logger.debug("ACL '%s' selected", cls.default_deny_acl.name)

        cls.vpc1 = VPC.create(cls.api_client,
                              cls.test_data['vpcs']['vpc1'],
                              vpcofferingid=cls.vpc_offering.id,
                              zoneid=cls.zone.id,
                              domainid=cls.domain.id,
                              account=cls.account.name)
        cls.logger.debug("VPC '%s' created, CIDR: %s", cls.vpc1.name, cls.vpc1.cidr)

        cls.network1 = Network.create(cls.api_client,
                                      cls.test_data['networks']['network1'],
                                      networkofferingid=cls.network_offering.id,
                                      aclid=cls.default_allow_acl.id,
                                      vpcid=cls.vpc1.id,
                                      zoneid=cls.zone.id,
                                      domainid=cls.domain.id,
                                      accountid=cls.account.name)
        cls.logger.debug("Network '%s' created, CIDR: %s, Gateway: %s", cls.network1.name, cls.network1.cidr, cls.network1.gateway)

        cls.vm1 = VirtualMachine.create(cls.api_client,
                                        cls.test_data['vms']['vm1'],
                                        templateid=cls.template.id,
                                        serviceofferingid=cls.virtual_machine_offering.id,
                                        networkids=[cls.network1.id],
                                        zoneid=cls.zone.id,
                                        domainid=cls.domain.id,
                                        accountid=cls.account.name)
        cls.logger.debug("VM '%s' created, Network: %s, IP %s", cls.vm1.name, cls.network1.name, cls.vm1.nic[0].ipaddress)

        cls.public_ip1 = PublicIPAddress.create(cls.api_client,
                                                zoneid=cls.zone.id,
                                                domainid=cls.account.domainid,
                                                accountid=cls.account.name,
                                                vpcid=cls.vpc1.id,
                                                networkid=cls.network1.id)
        cls.logger.debug("Public IP '%s' acquired, VPC: %s, Network: %s", cls.public_ip1.ipaddress, cls.vpc1.name, cls.network1.name)

        cls.nat_rule1 = NATRule.create(cls.api_client,
                                       cls.vm1,
                                       cls.test_data['nat_rule'],
                                       vpcid=cls.vpc1.id,
                                       networkid=cls.network1.id,
                                       ipaddressid=cls.public_ip1.id)
        cls.logger.debug("Port Forwarding Rule '%s (%s) %s => %s' created",