# 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.

""" P1 tests for primary storage limits

    Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domain+or+accounts

    Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-1466

    Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domains+and+accounts
"""
import unittest

from ddt import ddt, data
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.codes import (
    PASS,
    FAIL,
    RESOURCE_PRIMARY_STORAGE,
    CHILD_DOMAIN_ADMIN,
    ROOT_DOMAIN_ADMIN)
from marvin.lib.base import (
    Account,
    ServiceOffering,
    VirtualMachine,
    Domain,
    Volume,
    DiskOffering)
from marvin.lib.common import (
    get_domain,
    get_zone,
    get_template,
    matchResourceCount,
    createSnapshotFromVirtualMachineVolume,
    isVmExpunged,
    find_storage_pool_type)
from marvin.lib.utils import (cleanup_resources,
                              validateList)
# Import Local Modules
from nose.plugins.attrib import attr


@ddt
class TestVolumeLimits(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cloudstackTestClient = super(TestVolumeLimits,
                                     cls).getClsTestClient()
        cls.api_client = cloudstackTestClient.getApiClient()
        cls.hypervisor = cloudstackTestClient.getHypervisorInfo()
        # Fill services from the external config file
        cls.services = cloudstackTestClient.getParsedTestDataConfig()
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client)
        cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests())
        cls.services["mode"] = cls.zone.networktype
        cls._cleanup = []
        cls.unsupportedStorageType = False
        if cls.hypervisor.lower() == 'lxc':
            if not find_storage_pool_type(cls.api_client, storagetype='rbd'):
                cls.unsupportedStorageType = True
                return

        cls.template = get_template(
            cls.api_client,
            cls.zone.id,
            cls.services["ostype"]
        )

        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
        cls.services["virtual_machine"]["template"] = cls.template.id
        cls.services["volume"]["zoneid"] = cls.zone.id

        try:
            cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"])
            cls._cleanup.append(cls.service_offering)
        except Exception as e:
            cls.tearDownClass()
            raise unittest.SkipTest("Exception in setUpClass: %s" % e)
        return

    @classmethod
    def tearDownClass(cls):
        super(TestVolumeLimits, cls).tearDownClass()

    def setUp(self):
        if self.unsupportedStorageType:
            self.skipTest(
                "unsupported storage type")
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.cleanup = []
        try:
            self.services["disk_offering"]["disksize"] = 2
            self.disk_offering = DiskOffering.create(self.apiclient, self.services["disk_offering"])
            self.cleanup.append(self.disk_offering)
            self.assertNotEqual(self.disk_offering, None, \
                                "Disk offering is None")
        except Exception as e:
            self.tearDown()
            self.skipTest("Failure in setup: %s" % e)
        return

    def tearDown(self):
        super(TestVolumeLimits, self).tearDown()

    def setupAccount(self, accountType):
        """Setup the account required for the test"""

        try:
            if accountType == CHILD_DOMAIN_ADMIN:
                self.domain = Domain.create(self.apiclient,
                                            services=self.services["domain"],
                                            parentdomainid=self.domain.id)
                self.cleanup.append(self.domain)

            self.account = Account.create(self.apiclient, self.services["account"],
                                          domainid=self.domain.id, admin=True)
            self.cleanup.append(self.account)

            self.virtualMachine = VirtualMachine.create(self.api_client, self.services["virtual_machine"],
                                                        accountid=self.account.name, domainid=self.account.domainid,
                                                        diskofferingid=self.disk_offering.id,
                                                        serviceofferingid=self.service_offering.id,
                                                        startvm=False)
            self.cleanup.append(self.virtualMachine)

            accounts = Account.list(self.apiclient, id=self.account.id)

            self.assertEqual(validateList(accounts)[0], PASS,
                             "accounts list validation failed")

            self.initialResourceCount = int(accounts[0].primarystoragetotal)
        except Exception as e:
            return [FAIL, e]
        return [PASS, None]

    @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
    @attr(tags=["advanced", "basic"], required_hardware="false")
    def test_stop_start_vm(self, value):
        """Test Deploy VM with 5 GB volume & verify the usage

        # Validate the following
        # 1. Create a VM with custom disk offering and check the primary storage count
        # 2. Stop VM and verify the resource count remains same
        # 3. Start VM and verify resource count remains same"""

        response = self.setupAccount(value)
        self.assertEqual(response[0], PASS, response[1])

        expectedCount = self.initialResourceCount
        # Stopping instance
        try:
            self.virtualMachine.stop(self.apiclient)
        except Exception as e:
            self.fail("Failed to stop instance: %s" % e)
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        # Starting instance
        try:
            self.virtualMachine.start(self.apiclient)
        except Exception as e:
            self.fail("Failed to start instance: %s" % e)

        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])
        return

    @unittest.skip("skip")
    @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
    @attr(tags=["advanced", "basic"], required_hardware="false")
    def test_destroy_recover_vm(self, value):
        """Test delete and recover instance

        # Validate the following
        # 1. Create a VM with custom disk offering and check the primary storage count
        # 2. Destroy VM and verify the resource count remains same
        # 3. Recover VM and verify resource count remains same"""

        response = self.setupAccount(value)
        self.assertEqual(response[0], PASS, response[1])

        expectedCount = self.initialResourceCount
        # Stopping instance
        try:
            self.virtualMachine.delete(self.apiclient, expunge=False)
            self.cleanup.remove(self.virtualMachine)
        except Exception as e:
            self.fail("Failed to destroy instance: %s" % e)
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        # Recovering instance
        try:
            self.virtualMachine.recover(self.apiclient)
            self.cleanup.append(self.virtualMachine)
        except Exception as e:
            self.fail("Failed to start instance: %s" % e)

        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])
        return

    @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
    @attr(tags=["advanced", "basic"], required_hardware="false")
    def test_attach_detach_volume(self, value):
        """Stop attach and detach volume from VM

        # Validate the following
        # 1. Create a VM with custom disk offering and check the primary storage count
        #    of account
        # 2. Create custom volume in account
        # 3. Verify that primary storage count increases by same amount
        # 4. Attach volume to VM and verify resource count remains the same
        # 5. Detach volume and verify resource count remains the same"""

        response = self.setupAccount(value)
        self.assertEqual(response[0], PASS, response[1])

        apiclient = self.apiclient
        if value == CHILD_DOMAIN_ADMIN:
            apiclient = self.testClient.getUserApiClient(
                UserName=self.account.name,
                DomainName=self.account.domain
            )
            self.assertNotEqual(apiclient, FAIL, "Failure while getting\
                    api client of account: %s" % self.account.name)

        try:
            self.services["disk_offering"]["disksize"] = 4
            expectedCount = self.initialResourceCount + int(self.services["disk_offering"]["disksize"])
            disk_offering = DiskOffering.create(self.apiclient,
                                                services=self.services["disk_offering"])
            self.cleanup.append(disk_offering)

            volume = Volume.create(
                apiclient, self.services["volume"], zoneid=self.zone.id,
                account=self.account.name, domainid=self.account.domainid,
                diskofferingid=disk_offering.id)
            self.cleanup.append(volume)
        except Exception as e:
            self.fail("Failure: %s" % e)

        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        try:
            self.virtualMachine.attach_volume(apiclient, volume=volume)
            self.cleanup.remove(volume)
        except Exception as e:
            self.fail("Failed while attaching volume to VM: %s" % e)

        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        try:
            self.virtualMachine.detach_volume(apiclient, volume=volume)
            self.cleanup.append(volume)
        except Exception as e:
            self.fail("Failure while detaching volume: %s" % e)

        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])
        return

    @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
    @attr(tags=["advanced", "basic"], required_hardware="false")
    def test_create_multiple_volumes(self, value):
        """Test create multiple volumes

        # Validate the following
        # 1. Create a VM with custom disk offering and check the primary storage count
        #    of account
        # 2. Create multiple volumes in account
        # 3. Verify that primary storage count increases by same amount
        # 4. Attach volumes to VM and verify resource count remains the same
        # 5. Detach and delete both volumes one by one and verify resource count decreases
        #    proportionately"""

        # Creating service offering with 10 GB volume

        response = self.setupAccount(value)
        self.assertEqual(response[0], PASS, response[1])

        apiclient = self.apiclient
        if value == CHILD_DOMAIN_ADMIN:
            apiclient = self.testClient.getUserApiClient(
                UserName=self.account.name,
                DomainName=self.account.domain
            )
            self.assertNotEqual(apiclient, FAIL, "Failure while getting\
                                api client of account %s" % self.account.name)

        try:
            self.services["disk_offering"]["disksize"] = 5
            disk_offering_5_GB = DiskOffering.create(self.apiclient,
                                                     services=self.services["disk_offering"])
            self.cleanup.append(disk_offering_5_GB)

            self.services["disk_offering"]["disksize"] = 10
            disk_offering_10_GB = DiskOffering.create(self.apiclient,
                                                      services=self.services["disk_offering"])
            self.cleanup.append(disk_offering_10_GB)

            volume_1 = Volume.create(
                apiclient, self.services["volume"], zoneid=self.zone.id,
                account=self.account.name, domainid=self.account.domainid,
                diskofferingid=disk_offering_5_GB.id)
            self.debug("Attaching volume %s to vm %s" % (volume_1.name, self.virtualMachine.name))
            self.virtualMachine.attach_volume(apiclient, volume=volume_1)

            volume_2 = Volume.create(
                apiclient, self.services["volume"], zoneid=self.zone.id,
                account=self.account.name, domainid=self.account.domainid,
                diskofferingid=disk_offering_10_GB.id)
            self.debug("Attaching volume %s to vm %s" % (volume_2.name, self.virtualMachine.name))
            self.virtualMachine.attach_volume(apiclient, volume=volume_2)
        except Exception as e:
            self.fail("Failure: %s" % e)

        expectedCount = self.initialResourceCount + 15  # (5 + 10)
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        try:
            # Detaching and deleting volume 1
            self.virtualMachine.detach_volume(apiclient, volume=volume_1)
            volume_1.delete(apiclient)
        except Exception as e:
            self.fail("Failure while volume operation: %s" % e)

        expectedCount -= 5  # After deleting first volume
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        try:
            # Detaching and deleting volume 2
            self.virtualMachine.detach_volume(apiclient, volume=volume_2)
            volume_2.delete(apiclient)
        except Exception as e:
            self.fail("Failure while volume operation: %s" % e)

        expectedCount -= 10
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])
        return

    @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
    @attr(tags=["advanced", "basic"], required_hardware="false")
    def test_deploy_multiple_vm(self, value):
        """Test Deploy multiple VMs with & verify the usage
        # Validate the following
        # 1. Deploy multiple VMs with this service offering
        # 2. Update Resource count for the root admin Primary Storage usage
        # 3. Primary Storage usage should list properly
        # 4. Destroy one VM among multiple VM's and verify that primary storage count
        #  decreases by equivalent amount
        """

        response = self.setupAccount(value)
        self.assertEqual(response[0], PASS, response[1])

        self.virtualMachine_2 = VirtualMachine.create(self.api_client, self.services["virtual_machine"],
                                                      accountid=self.account.name, domainid=self.account.domainid,
                                                      diskofferingid=self.disk_offering.id,
                                                      serviceofferingid=self.service_offering.id)
        self.cleanup.append(self.virtualMachine_2)

        expectedCount = (self.initialResourceCount * 2)  # Total 2 vms
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        self.virtualMachine_3 = VirtualMachine.create(self.api_client, self.services["virtual_machine"],
                                                      accountid=self.account.name, domainid=self.account.domainid,
                                                      diskofferingid=self.disk_offering.id,
                                                      serviceofferingid=self.service_offering.id)
        self.cleanup.append(self.virtualMachine_3)

        expectedCount = (self.initialResourceCount * 3)  # Total 3 vms
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        self.debug("Destroying instance: %s" % self.virtualMachine_2.name)
        try:
            self.virtualMachine_2.delete(self.apiclient)
            self.cleanup.remove(self.virtualMachine_2)
        except Exception as e:
            self.fail("Failed to delete instance: %s" % e)

        self.assertTrue(isVmExpunged(self.apiclient, self.virtualMachine_2.id), "VM not expunged \
                in allotted time")

        expectedCount -= (self.template.size / (1024 ** 3))
        response = matchResourceCount(
            self.apiclient, int(expectedCount),
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])
        return

    @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
    @attr(tags=["advanced", "basic", "selfservice"])
    def test_assign_vm_different_account(self, value):
        """Test assign Vm to different account
        # Validate the following
        # 1. Deploy VM in account and check the primary storage resource count
        # 2. Assign VM to another account
        # 3. Resource count for first account should now equal to 0
        # 4. Resource count for the account to which VM is assigned should
        #    increase to that of initial resource count of first account
        """

        response = self.setupAccount(value)
        self.assertEqual(response[0], PASS, response[1])

        try:
            account_2 = Account.create(self.apiclient, self.services["account"],
                                       domainid=self.domain.id, admin=True)
            self.cleanup.append(account_2)
        except Exception as e:
            self.fail("Failed to create account: %s" % e)

        expectedCount = self.initialResourceCount
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        try:
            self.virtualMachine.stop(self.apiclient)
            self.virtualMachine.assign_virtual_machine(self.apiclient,
                                                       account_2.name, account_2.domainid)
            self.cleanup.remove(self.virtualMachine)  # should now be cleaned with account_2
            self.cleanup.append(self.virtualMachine)  # or before to be neat
        except Exception as e:
            self.fail("Failed to assign virtual machine to account %s: %s" %
                      (account_2.name, e))

        # Checking resource count for account 2
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=account_2.id)
        self.assertEqual(response[0], PASS, response[1])

        expectedCount = 0
        # Checking resource count for original account
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])
        return

    @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN)
    # @attr(tags=["advanced", "basic"], required_hardware="true")
    @attr(tags=["TODO"], required_hardware="true")
    def test_create_template_snapshot(self, value):
        """Test create snapshot and templates from volume

        # Validate the following
        # 1. Deploy VM with custoom disk offering and check the
        #    primary storage resource count
        # 2. Stop the VM and create Snapshot from VM's volume
        # 3. Create volume againt from this snapshto and attach to VM
        # 4. Verify that primary storage count increases by the volume size
        # 5. Detach and delete volume, verify primary storage count decreaes by volume size"""
        if self.hypervisor.lower() in ['hyperv']:
            self.skipTest("Snapshots feature is not supported on Hyper-V")
        response = self.setupAccount(value)
        self.debug(response[0])
        self.debug(response[1])
        self.assertEqual(response[0], PASS, response[1])
        apiclient = self.apiclient
        try:
            self.virtualMachine.start(apiclient)
        except Exception as e:
            self.fail("Failed to start instance: %s" % e)

        if value == CHILD_DOMAIN_ADMIN:
            apiclient = self.testClient.getUserApiClient(
                UserName=self.account.name,
                DomainName=self.account.domain
            )
            self.assertNotEqual(apiclient, FAIL, "Failure while getting api\
                    client of account: %s" % self.account.name)

        try:
            self.virtualMachine.stop(apiclient)
        except Exception as e:
            self.fail("Failed to stop instance: %s" % e)
        expectedCount = self.initialResourceCount
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        self.debug("Creating snapshot from ROOT volume: %s" % self.virtualMachine.name)
        snapshot = None
        response = createSnapshotFromVirtualMachineVolume(apiclient, self.account, self.virtualMachine.id)
        self.assertEqual(response[0], PASS, response[1])
        snapshot = response[1]
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        try:
            self.services["volume"]["size"] = self.services["disk_offering"]["disksize"]
            volume = Volume.create_from_snapshot(apiclient,
                                                 snapshot_id=snapshot.id,
                                                 services=self.services["volume"],
                                                 account=self.account.name,
                                                 domainid=self.account.domainid)
            self.debug("Attaching the volume to vm: %s" % self.virtualMachine.name)
            self.virtualMachine.attach_volume(apiclient, volume)
        except Exception as e:
            self.fail("Failure in volume operation: %s" % e)

        expectedCount += int(self.services["volume"]["size"])
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])

        try:
            self.virtualMachine.detach_volume(apiclient, volume)
            self.cleanup.append(volume)
        except Exception as e:
            self.fail("Failure in detach volume operation: %s" % e)

        try:
            self.debug("deleting the volume: %s" % volume.name)
            volume.delete(apiclient)
            self.cleanup.remove(volume)
        except Exception as e:
            self.fail("Failure while deleting volume: %s" % e)

        expectedCount -= int(self.services["volume"]["size"])
        response = matchResourceCount(
            self.apiclient, expectedCount,
            RESOURCE_PRIMARY_STORAGE,
            accountid=self.account.id)
        self.assertEqual(response[0], PASS, response[1])
        return
