# Copyright 2016 AT&T Corp
# All Rights Reserved.
#
#    Licensed 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.

import time

from oslo_log import log as logging
from ranger_tempest_plugin.data_utils import data_utils
from ranger_tempest_plugin.tests.api import base

from tempest import config
from tempest.lib import exceptions

CONF = config.CONF
LOG = logging.getLogger(__name__)


class RmsBaseOrmTest(base.BaseOrmTest):

    @classmethod
    def resource_setup(cls):
        super(RmsBaseOrmTest, cls).resource_setup()
        cls.setup_ids = []

        # create standard region
        _, cls.region_1 = cls.client.create_region(**cls._get_region_params())
        cls.setup_ids.append(cls.region_1['id'])

        # create region sharing region_1 properties
        another_region = cls._get_region_params()
        another_region['metadata'] = {'key2': ['value2']}
        _, cls.region_2 = cls.client.create_region(**another_region)
        cls.setup_ids.append(cls.region_2['id'])

        for region_id in cls.setup_ids:
            cls.addClassResourceCleanup(cls.client.delete_region, region_id)

        # create customer
        customer_parms = cls._get_customer_params()
        cls.setup_customer = \
            cls._create_customer_validate_creation(**customer_parms)

    @classmethod
    def setup_clients(cls):
        super(RmsBaseOrmTest, cls).setup_clients()
        cls.client = cls.os_primary.rms_client
        cls.cms_client = cls.os_primary.cms_client

    @classmethod
    def _get_region_params(cls):
        identity_url = CONF.identity.uri_v3 or ""
        identity_url = identity_url.strip('/v3')
        region_id = data_utils.rand_name()

        region = {}
        region = {
            'status': 'functional',
            'name': region_id,
            'id': region_id,
            'description': region_id,
            'designType': 'Cruiser',
            'locationType': 'testlocation',
            'vlcpName': region_id,
            'address': {
                'country': 'usa',
                'state': 'tx',
                'city': 'austin',
                'street': '12 main',
                'zip': '12345'
            },
            'metadata': {
                'key': ['value'],
                'key2': ['value2']
            },
            'endpoints': [
                {
                    'publicURL':
                        'https://dashboard-nc.%s.cci.att.com' % region_id,
                    'type': 'dashboard'
                },
                {
                    'publicURL': identity_url,
                    'type': 'identity'
                },
                {
                    'publicURL':
                        'https://ranger-agent-nc.%s.cci.att.com' % region_id,
                    'type': 'ord'
                },

            ],
            'rangerAgentVersion': '2.0',
            'OSVersion': 'Stein',
            'CLLI': 'testclli'
        }

        return region

    @classmethod
    def _get_customer_params(cls):
        customer = {}
        customer['description'] = data_utils.rand_name('ormTempestRms')
        customer['enabled'] = True
        customer['name'] = data_utils.rand_name('ormTempestRms')
        customer['regions'] = [{'name': CONF.identity.region}]
        customer['defaultQuotas'] = []
        customer['users'] = []
        return customer

    @classmethod
    def _wait_for_status(cls, customer_id, status):
        _, customer = cls.cms_client.get_customer(customer_id)
        customer_status = customer["status"]
        start = int(time.time())
        while customer_status != status:
            time.sleep(cls.build_interval)
            _, customer = cls.cms_client.get_customer(customer_id)
            customer_status = customer["status"]

            if customer_status == 'Error':
                message = ""
                for region in customer["regions"]:
                    if "error_message" in region:
                        message += "Region %s Error: %s. " % (
                            region["name"], region["error_message"])

                if not message:
                    message = ('Customer %s failed to reach %s status and is'
                               ' in ERROR status' % (customer_id, status))
                raise exceptions.ServerFault(message)

            if int(time.time()) - start >= cls.build_timeout:
                message = ('Customer %s failed to reach %s'
                           'status within the required time (%s s)'
                           'and is in %s status.'
                           % (customer_id, status,
                              cls.build_timeout,
                              customer_status))
                raise exceptions.TimeoutException(message)

    @classmethod
    def _create_customer_validate_creation(cls, **kwargs):
        _, body = cls.cms_client.create_customer(**kwargs)
        customer_id = body['customer']['id']

        cls.addClassResourceCleanup(
            cls._delete_customer_validate_deletion, customer_id)

        cls._wait_for_status(customer_id, 'Success')
        _, customer = cls.cms_client.get_customer(customer_id)
        return customer

    @classmethod
    def _delete_customer_validate_deletion(cls, customer_id):
        _, customer = cls.cms_client.get_customer(customer_id)
        regions_on_customer = \
            [region['name'] for region in customer['regions']]

        for region in regions_on_customer:
            cls.cms_client.delete_region_from_customer(customer_id, region)

        cls._wait_for_status(customer_id, 'no regions')
        cls.cms_client.delete_customer(customer_id)