# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

"""
Tests of acquiring a specified public IP for isolated network or vpc
"""

# Import Local Modules
from nose.plugins.attrib import attr
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
from marvin.cloudstackAPI import createVlanIpRange
from marvin.lib.utils import (validateList,
                              cleanup_resources)
from marvin.lib.base import (Account,
                             Domain,
                             Configurations,
                             VirtualMachine,
                             ServiceOffering,
                             VpcOffering,
                             Zone,
                             Network,
                             VPC,
                             PublicIPAddress,
                             PublicIpRange)
from marvin.lib.common import (get_domain,
                               get_zone,
                               get_free_vlan,
                               get_template)
import logging
import random

class TestAcquireSpecifiedPublicIp(cloudstackTestCase):
    @classmethod
    def setUpClass(cls):
        cls.testClient = super(
            TestAcquireSpecifiedPublicIp,
            cls).getClsTestClient()
        cls.apiclient = cls.testClient.getApiClient()
        cls.services = cls.testClient.getParsedTestDataConfig()

        zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
        cls.zone = Zone(zone.__dict__)
        cls.template = get_template(cls.apiclient, cls.zone.id)
        cls._cleanup = []

        if str(cls.zone.securitygroupsenabled) == "True":
            sys.exit(1)

        cls.logger = logging.getLogger("TestAcquireSpecifiedPublicIp")
        cls.stream_handler = logging.StreamHandler()
        cls.logger.setLevel(logging.DEBUG)
        cls.logger.addHandler(cls.stream_handler)

        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.apiclient)

        # Create new domain1
        cls.domain1 = Domain.create(
            cls.apiclient,
            services=cls.services["acl"]["domain1"],
            parentdomainid=cls.domain.id)

        # Create account1
        cls.account1 = Account.create(
            cls.apiclient,
            cls.services["acl"]["accountD1"],
            domainid=cls.domain1.id
        )

        # Create domain2
        cls.domain2 = Domain.create(
            cls.apiclient,
            services=cls.services["acl"]["domain2"],
            parentdomainid=cls.domain.id)

        # Create account2
        cls.account2 = Account.create(
            cls.apiclient,
            cls.services["acl"]["accountD2"],
            domainid=cls.domain2.id
        )

        cls.services["publiciprange"]["zoneid"] = cls.zone.id
        cls.services["publiciprange"]["forvirtualnetwork"] = "true"

        # Create public ip range 1
        cls.services["publiciprange"]["vlan"] = get_free_vlan(
            cls.apiclient,
            cls.zone.id)[1]
        random_subnet_number = random.randrange(10,20)
        cls.services["publiciprange"]["gateway"] = "172.16." + \
            str(random_subnet_number) + ".1"
        cls.services["publiciprange"]["startip"] = "172.16." + \
            str(random_subnet_number) + ".2"
        cls.services["publiciprange"]["endip"] = "172.16." + \
            str(random_subnet_number) + ".10"
        cls.services["publiciprange"]["netmask"] = "255.255.255.0"
        cls.public_ip_range1 = PublicIpRange.create(
            cls.apiclient,
            cls.services["publiciprange"]
        )
        PublicIpRange.dedicate(
            cls.apiclient,
            cls.public_ip_range1.vlan.id,
            domainid=cls.account1.domainid
        )

        # Create public ip range 2
        cls.services["publiciprange"]["vlan"] = get_free_vlan(
            cls.apiclient,
            cls.zone.id)[1]
        cls.services["publiciprange"]["gateway"] = "172.16." + \
            str(random_subnet_number + 1) + ".1"
        cls.services["publiciprange"]["startip"] = "172.16." + \
            str(random_subnet_number + 1) + ".2"
        cls.services["publiciprange"]["endip"] = "172.16." + \
            str(random_subnet_number + 1) + ".10"
        cls.services["publiciprange"]["netmask"] = "255.255.255.0"
        cls.public_ip_range2 = PublicIpRange.create(
            cls.apiclient,
            cls.services["publiciprange"]
        )
        PublicIpRange.dedicate(
            cls.apiclient,
            cls.public_ip_range2.vlan.id,
            account=cls.account1.name,
            domainid=cls.account1.domainid
        )

        # Create public ip range 3
        cls.services["publiciprange"]["vlan"] = get_free_vlan(
            cls.apiclient,
            cls.zone.id)[1]
        cls.services["publiciprange"]["gateway"] = "172.16." + \
            str(random_subnet_number + 2) + ".1"
        cls.services["publiciprange"]["startip"] = "172.16." + \
            str(random_subnet_number + 2) + ".2"
        cls.services["publiciprange"]["endip"] = "172.16." + \
            str(random_subnet_number + 2) + ".10"
        cls.services["publiciprange"]["netmask"] = "255.255.255.0"
        cls.public_ip_range3 = PublicIpRange.create(
            cls.apiclient,
            cls.services["publiciprange"]
        )