# 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.
from __builtin__ import False
""" Tests for Secondary Storage with Local Storage
"""

# Import Local Modules
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from marvin.lib.utils import *
from marvin.lib.base import *
from marvin.lib.common import *
from nose.plugins.attrib import attr

_multiprocess_shared_ = False


class TestSecSRMount(cloudstackTestCase):

    def setUp(self):
        self.logger = logging.getLogger('TestSecSRMount')
        self.stream_handler = logging.StreamHandler()
        self.logger.setLevel(logging.DEBUG)
        self.logger.addHandler(self.stream_handler)
        self.apiclient = self.testClient.getApiClient()
        self.hypervisor = self.testClient.getHypervisorInfo()
        self.dbclient = self.testClient.getDbConnection()
        self.services = self.testClient.getParsedTestDataConfig()
        self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
        self.pod = get_pod(self.apiclient, self.zone.id)
        self.cleanup = []
        self.services = {
                            "service_offering_local": {
                                "name": "Ultra Tiny Local Instance",
                                "displaytext": "Ultra Tiny Local Instance",
                                "cpunumber": 1,
                                "cpuspeed": 100,
                                "memory": 128,
                                "storagetype": "local"
                            },
                            "vm": {
                                "username": "root",
                                "password": "password",
                                "ssh_port": 22,
                                # Hypervisor type should be same as
                                # hypervisor type of cluster
                                "privateport": 22,
                                "publicport": 22,
                                "protocol": 'TCP',
                            },
                         "ostype": 'CentOS 5.3 (64-bit)',
                         "sleep": 30,
                         "timeout": 10,
                         }


    def tearDown(self):
        try:
            # Clean up, terminate the created templates
            cleanup_resources(self.apiclient, self.cleanup)

        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

        return

    def isOnlyLocalStorageAvailable(self):
        if not self.zone.localstorageenabled:
            self.skipTest("Local Storage not enabled")

        storage_pools = StoragePool.list(
                   self.apiclient,
                   zoneid=self.zone.id,
                   listall=True
                    )
        self.assertEqual(
                           isinstance(storage_pools, list),
                           True,
                           "Check if listStoragePools returns a valid response"
                           )
        for storage_pool in storage_pools:
            if storage_pool.type == u'NetworkFilesystem':
                return False
            
        return True

    def download(self, apiclient, template_id, retries=12, interval=5):
        """Check if template download will finish in 1 minute"""
        while retries > -1:
            time.sleep(interval)
            template_response = Template.list(
                apiclient,
                id=template_id,
                zoneid=self.zone.id,
                templatefilter='self'
            )

            if isinstance(template_response, list):
                template = template_response[0]
                if not hasattr(template, 'status') or not template or not template.status:
                    retries = retries - 1
                    continue

                # If template is ready,
                # template.status = Download Complete
                # Downloading - x% Downloaded
                # if Failed
                # Error - Any other string
                if 'Failed' in template.status:
                    raise Exception(
                        "Failed to download template: status - %s" %
                        template.status)

                elif template.status == 'Download Complete' and template.isready:
                    return

                elif 'Downloaded' in template.status:
                    retries = retries - 1
                    continue

                elif 'Installing' not in template.status:
                    if retries >= 0:
                        retries = retries - 1
                        continue
                    raise Exception(
                        "Error in downloading template: status - %s" %
                        template.status)

            else:
                retries = retries - 1
        raise Exception("Template download failed exception.")

    @attr(
        tags=[
            "advanced",
            "xenserver"],
        required_hardware="true")
    def test_01_prepare_template_local_storage(self):
    
        if not self.isOnlyLocalStorageAvailable():
            self.skipTest("Skipping this test as this is for Local storage on only.")
        
        listHost = Host.list(
            self.apiclient,
            type='Routing',
            zoneid=self.zone.id,
            podid=self.pod.id,
        )
        for host in listHost:
            self.logger.debug('Host id %s, hypervisor %s, localstorage %s' % (host.id, host.hypervisor, host.islocalstorageactive))
                  
        if len(listHost) < 2:
            self.logger.debug("Prepare secondary storage race condition can be tested with two or more host only %s, found" % len(listHost));
            self.skipTest("Prepare secondary storage can be tested with two host only %s, found" % len(listHost))
        
        list_template_response = Template.list(
                                            self.apiclient,
                                            templatefilter='all',
                                            zoneid=self.zone.id)
        
        template_response = list_template_response[0]
        
        self.logger.debug('Template id %s is Ready %s' % (template_response.id, template_response.isready))
        
        if template_response.isready != True:
            self.skipTest('Template id %s is Not Ready' % (template_response.id))

        try:
            cmd = prepareTemplate.prepareTemplateCmd()
            cmd.zoneid = self.zone.id
            cmd.templateid = template_response.id
            result = self.apiclient.prepareTemplate(cmd)
            self.logger.debug('Prepare Template result %s' % result)
        except Exception as e:
           raise Exception("Warning: Exception during prepare template : %s" % e)

        self.download(self.apiclient, template_response.id)
        return
