# Copyright 2013 IBM Corp.
#
#    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 netaddr

from tempest import auth
from tempest import clients
from tempest.common import cred_provider
from tempest.common.utils import data_utils
from tempest import config
from tempest import exceptions
from tempest.openstack.common import log as logging

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


class IsolatedCreds(cred_provider.CredentialProvider):

    def __init__(self, name, tempest_client=True, interface='json',
                 password='pass', network_resources=None):
        super(IsolatedCreds, self).__init__(name, tempest_client, interface,
                                            password, network_resources)
        self.network_resources = network_resources
        self.isolated_creds = {}
        self.isolated_net_resources = {}
        self.ports = []
        self.tempest_client = tempest_client
        self.interface = interface
        self.password = password
        self.identity_admin_client, self.network_admin_client = (
            self._get_admin_clients())

    def _get_admin_clients(self):
        """
        Returns a tuple with instances of the following admin clients (in this
        order):
            identity
            network
        """
        if self.tempest_client:
            os = clients.AdminManager(interface=self.interface)
        else:
            os = clients.OfficialClientManager(
                auth.get_default_credentials('identity_admin')
            )
        return os.identity_client, os.network_client

    def _create_tenant(self, name, description):
        if self.tempest_client:
            _, tenant = self.identity_admin_client.create_tenant(
                name=name, description=description)
        else:
            tenant = self.identity_admin_client.tenants.create(
                name,
                description=description)
        return tenant

    def _get_tenant_by_name(self, name):
        if self.tempest_client:
            _, tenant = self.identity_admin_client.get_tenant_by_name(name)
        else:
            tenants = self.identity_admin_client.tenants.list()
            for ten in tenants:
                if ten['name'] == name:
                    tenant = ten
                    break
            else:
                raise exceptions.NotFound('No such tenant')
        return tenant

    def _create_user(self, username, password, tenant, email):
        if self.tempest_client:
            _, user = self.identity_admin_client.create_user(username,
                                                             password,
                                                             tenant['id'],
                                                             email)
        else:
            user = self.identity_admin_client.users.create(username, password,
                                                           email,
                                                           tenant_id=tenant.id)
        return user

    def _get_user(self, tenant, username):
        if self.tempest_client:
            _, user = self.identity_admin_client.get_user_by_username(
                tenant['id'],
                username)
        else:
            user = self.identity_admin_client.users.get(username)
        return user

    def _list_roles(self):
        if self.tempest_client:
            _, roles = self.identity_admin_client.list_roles()
        else:
            roles = self.identity_admin_client.roles.list()
        return roles

    def _assign_user_role(self, tenant, user, role_name):
        role = None
        try:
            roles = self._list_roles()
            if self.tempest_client:
                role = next(r for r in roles if r['name'] == role_name)
            else:
                role = next(r for r in roles if r.name == role_name)
        except StopIteration:
            msg = 'No "%s" role found' % role_name
            raise exceptions.NotFound(msg)
        if self.tempest_client:
            self.identity_admin_client.assign_user_role(tenant['id'],
                                                        user['id'], role['id'])
        else:
            self.identity_admin_client.roles.add_user_role(user.id, role.id,
                                                           tenant.id)

    def _delete_user(self, user):
        if self.tempest_client:
            self.identity_admin_client.delete_user(user)
        else:
            self.identity_admin_client.users.delete(user)

    def _delete_tenant(self, tenant):
        if self.tempest_client:
            self.identity_admin_client.delete_tenant(tenant)
        else:
            self.identity_admin_client.tenants.delete(tenant)

    def _create_creds(self, suffix="", admin=False):
        """Create random credentials under the following schema.

        If the name contains a '.' is the full class path of something, and
        we don't really care. If it isn't, it's probably a meaningful name,
        so use it.

        For logging purposes, -user and -tenant are long and redundant,
        don't use them. The user# will be sufficient to figure it out.
        """
        if '.' in self.name:
            root = ""
        else:
            root = self.name

        tenant_name = data_utils.rand_name(root) + suffix
        tenant_desc = tenant_name + "-desc"
        tenant = self._create_tenant(name=tenant_name,
                                     description=tenant_desc)

        username = data_utils.rand_name(root) + suffix
        email = data_utils.rand_name(root) + suffix + "@example.com"
        user = self._create_user(username, self.password,
                                 tenant, email)
        if CONF.service_available.swift:
            # NOTE(andrey-mp): user needs this role to create containers
            # in swift
            swift_operator_role = CONF.object_storage.operator_role
            self._assign_user_role(tenant, user, swift_operator_role)
        if admin:
            self._assign_user_role(tenant, user, CONF.identity.admin_role)
        return self._get_credentials(user, tenant)

    def _get_credentials(self, user, tenant):
        if self.tempest_client:
            user_get = user.get
            tenant_get = tenant.get
        else:
            user_get = user.__dict__.get
            tenant_get = tenant.__dict__.get
        return auth.get_credentials(
            username=user_get('name'), user_id=user_get('id'),
            tenant_name=tenant_get('name'), tenant_id=tenant_get('id'),
            password=self.password)

    def _create_network_resources(self, tenant_id):
        network = None
        subnet = None
        router = None
        # Make sure settings
        if self.network_resources:
            if self.network_resources['router']:
                if (not self.network_resources['subnet'] or
                    not self.network_resources['network']):
                    raise exceptions.InvalidConfiguration(
                        'A router requires a subnet and network')
            elif self.network_resources['subnet']:
                if not self.network_resources['network']:
                    raise exceptions.InvalidConfiguration(
                        'A subnet requires a network')
            elif self.network_resources['dhcp']:
                raise exceptions.InvalidConfiguration('DHCP requires a subnet')

        data_utils.rand_name_root = data_utils.rand_name(self.name)
        if not self.network_resources or self.network_resources['network']:
            network_name = data_utils.rand_name_root + "-network"
            network = self._create_network(network_name, tenant_id)
        try:
            if not self.network_resources or self.network_resources['subnet']:
                subnet_name = data_utils.rand_name_root + "-subnet"
                subnet = self._create_subnet(subnet_name, tenant_id,
                                             network['id'])
            if not self.network_resources or self.network_resources['router']:
                router_name = data_utils.rand_name_root + "-router"
                router = self._create_router(router_name, tenant_id)
                self._add_router_interface(router['id'], subnet['id'])
        except Exception:
            if router:
                self._clear_isolated_router(router['id'], router['name'])
            if subnet:
                self._clear_isolated_subnet(subnet['id'], subnet['name'])
            if network:
                self._clear_isolated_network(network['id'], network['name'])
            raise
        return network, subnet, router

    def _create_network(self, name, tenant_id):
        if self.tempest_client:
            resp, resp_body = self.network_admin_client.create_network(
                name=name, tenant_id=tenant_id)
        else:
            body = {'network': {'tenant_id': tenant_id, 'name': name}}
            resp_body = self.network_admin_client.create_network(body)
        return resp_body['network']

    def _create_subnet(self, subnet_name, tenant_id, network_id):
        if not self.tempest_client:
            body = {'subnet': {'name': subnet_name, 'tenant_id': tenant_id,
                               'network_id': network_id, 'ip_version': 4}}
            if self.network_resources:
                body['enable_dhcp'] = self.network_resources['dhcp']
        base_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
        mask_bits = CONF.network.tenant_network_mask_bits
        for subnet_cidr in base_cidr.subnet(mask_bits):
            try:
                if self.tempest_client:
                    if self.network_resources:
                        resp, resp_body = self.network_admin_client.\
                            create_subnet(
                                network_id=network_id, cidr=str(subnet_cidr),
                                name=subnet_name,
                                tenant_id=tenant_id,
                                enable_dhcp=self.network_resources['dhcp'],
                                ip_version=4)
                    else:
                        resp, resp_body = self.network_admin_client.\
                            create_subnet(network_id=network_id,
                                          cidr=str(subnet_cidr),
                                          name=subnet_name,
                                          tenant_id=tenant_id,
                                          ip_version=4)
                else:
                    body['subnet']['cidr'] = str(subnet_cidr)
                    resp_body = self.network_admin_client.create_subnet(body)
                break
            except exceptions.BadRequest as e:
                if 'overlaps with another subnet' not in str(e):
                    raise
        else:
            e = exceptions.BuildErrorException()
            e.message = 'Available CIDR for subnet creation could not be found'
            raise e
        return resp_body['subnet']

    def _create_router(self, router_name, tenant_id):
        external_net_id = dict(
            network_id=CONF.network.public_network_id)
        if self.tempest_client:
            resp, resp_body = self.network_admin_client.create_router(
                router_name,
                external_gateway_info=external_net_id,
                tenant_id=tenant_id)
        else:
            body = {'router': {'name': router_name, 'tenant_id': tenant_id,
                               'external_gateway_info': external_net_id,
                               'admin_state_up': True}}
            resp_body = self.network_admin_client.create_router(body)
        return resp_body['router']

    def _add_router_interface(self, router_id, subnet_id):
        if self.tempest_client:
            self.network_admin_client.add_router_interface_with_subnet_id(
                router_id, subnet_id)
        else:
            body = {'subnet_id': subnet_id}
            self.network_admin_client.add_interface_router(router_id, body)

    def get_primary_network(self):
        return self.isolated_net_resources.get('primary')[0]

    def get_primary_subnet(self):
        return self.isolated_net_resources.get('primary')[1]

    def get_primary_router(self):
        return self.isolated_net_resources.get('primary')[2]

    def get_admin_network(self):
        return self.isolated_net_resources.get('admin')[0]

    def get_admin_subnet(self):
        return self.isolated_net_resources.get('admin')[1]

    def get_admin_router(self):
        return self.isolated_net_resources.get('admin')[2]

    def get_alt_network(self):
        return self.isolated_net_resources.get('alt')[0]

    def get_alt_subnet(self):
        return self.isolated_net_resources.get('alt')[1]

    def get_alt_router(self):
        return self.isolated_net_resources.get('alt')[2]

    def get_credentials(self, credential_type):
        if self.isolated_creds.get(credential_type):
            credentials = self.isolated_creds[credential_type]
        else:
            is_admin = (credential_type == 'admin')
            credentials = self._create_creds(admin=is_admin)
            self.isolated_creds[credential_type] = credentials
            # Maintained until tests are ported
            LOG.info("Acquired isolated creds:\n credentials: %s"
                     % credentials)
            if (CONF.service_available.neutron and
                not CONF.baremetal.driver_enabled):
                network, subnet, router = self._create_network_resources(
                    credentials.tenant_id)
                self.isolated_net_resources[credential_type] = (
                    network, subnet, router,)
                LOG.info("Created isolated network resources for : \n"
                         + " credentials: %s" % credentials)
        return credentials

    def get_primary_creds(self):
        return self.get_credentials('primary')

    def get_admin_creds(self):
        return self.get_credentials('admin')

    def get_alt_creds(self):
        return self.get_credentials('alt')

    def _clear_isolated_router(self, router_id, router_name):
        net_client = self.network_admin_client
        try:
            net_client.delete_router(router_id)
        except exceptions.NotFound:
            LOG.warn('router with name: %s not found for delete' %
                     router_name)

    def _clear_isolated_subnet(self, subnet_id, subnet_name):
        net_client = self.network_admin_client
        try:
            net_client.delete_subnet(subnet_id)
        except exceptions.NotFound:
            LOG.warn('subnet with name: %s not found for delete' %
                     subnet_name)

    def _clear_isolated_network(self, network_id, network_name):
        net_client = self.network_admin_client
        try:
            net_client.delete_network(network_id)
        except exceptions.NotFound:
            LOG.warn('network with name: %s not found for delete' %
                     network_name)

    def _clear_isolated_net_resources(self):
        net_client = self.network_admin_client
        for cred in self.isolated_net_resources:
            network, subnet, router = self.isolated_net_resources.get(cred)
            LOG.debug("Clearing network: %(network)s, "
                      "subnet: %(subnet)s, router: %(router)s",
                      {'network': network, 'subnet': subnet, 'router': router})
            if (not self.network_resources or
                self.network_resources.get('router')):
                try:
                    if self.tempest_client:
                        net_client.remove_router_interface_with_subnet_id(
                            router['id'], subnet['id'])
                    else:
                        body = {'subnet_id': subnet['id']}
                        net_client.remove_interface_router(router['id'], body)
                except exceptions.NotFound:
                    LOG.warn('router with name: %s not found for delete' %
                             router['name'])
                self._clear_isolated_router(router['id'], router['name'])
            if (not self.network_resources or
                self.network_resources.get('subnet')):
                self._clear_isolated_subnet(subnet['id'], subnet['name'])
            if (not self.network_resources or
                self.network_resources.get('network')):
                self._clear_isolated_network(network['id'], network['name'])

    def clear_isolated_creds(self):
        if not self.isolated_creds:
            return
        self._clear_isolated_net_resources()
        for creds in self.isolated_creds.itervalues():
            try:
                self._delete_user(creds.user_id)
            except exceptions.NotFound:
                LOG.warn("user with name: %s not found for delete" %
                         creds.username)
            try:
                self._delete_tenant(creds.tenant_id)
            except exceptions.NotFound:
                LOG.warn("tenant with name: %s not found for delete" %
                         creds.tenant_name)
