# -*- coding: utf-8 -*-
'''
Management of Neutron resources
===============================
:depends:   - neutronclient Python module
:configuration: See :py:mod:`salt.modules.neutron` for setup instructions.
.. code-block:: yaml
    neutronng network present:
      neutronng.network_present:
        - name: Netone
        - provider_physical_network: PHysnet1
        - provider_network_type: vlan
'''
import logging
from functools import wraps
LOG = logging.getLogger(__name__)


def __virtual__():
    '''
    Only load if neutron module is present in __salt__
    '''
    return 'neutronng' if 'neutron.list_networks' in __salt__ else False


def _test_call(method):
    (resource, functionality) = method.func_name.split('_')
    if functionality == 'present':
        functionality = 'updated'
    else:
        functionality = 'removed'

    @wraps(method)
    def check_for_testing(name, *args, **kwargs):
        if __opts__.get('test', None):
            return _no_change(name, resource, test=functionality)
        return method(name, *args, **kwargs)
    return check_for_testing


def _neutron_module_call(method, *args, **kwargs):
    return __salt__['neutronng.{0}'.format(method)](*args, **kwargs)

def _get_tenant_id(tenant_name, *args, **kwargs):
    try:
        tenant_id = __salt__['keystone.tenant_get'](
            name=tenant_name, **kwargs)[tenant_name]['id']
    except:
        tenant_id = None
        LOG.debug('Cannot get the tenant id. User {0} is not an admin.'.format(
            kwargs.get('connection_user')))
    return tenant_id

def _auth(profile=None, endpoint_type=None):
    '''
    Set up neutron credentials
    '''
    if profile:
        credentials = __salt__['config.option'](profile)
        user = credentials['keystone.user']
        password = credentials['keystone.password']
        tenant = credentials['keystone.tenant']
        auth_url = credentials['keystone.auth_url']
    kwargs = {
        'connection_user': user,
        'connection_password': password,
        'connection_tenant': tenant,
        'connection_auth_url': auth_url,
        'connection_endpoint_type': endpoint_type,
        'profile': profile
    }

    return kwargs

@_test_call
def network_present(name=None,
                    network_id=None,
                    tenant=None,
                    provider_network_type=None,
                    provider_physical_network=None,
                    router_external=None,
                    admin_state_up=None,
                    shared=None,
                    provider_segmentation_id=None,
                    profile=None,
                    endpoint_type=None):
    '''
    Ensure that the neutron network is present with the specified properties.
    name
        The name of the network to manage
    '''
    connection_args = _auth(profile, endpoint_type)
    tenant_id = _get_tenant_id(tenant_name=tenant, **connection_args)

    existing_networks = _neutron_module_call(
        'list_networks', name=name, tenant_id=tenant_id,
        **connection_args)['networks']
    network_arguments = _get_non_null_args(
        name=name,
        provider_network_type=provider_network_type,
        provider_physical_network=provider_physical_network,
        router_external=router_external,
        admin_state_up=admin_state_up,
        shared=shared,
        tenant_id=tenant_id,
        provider_segmentation_id=provider_segmentation_id)

    if len(existing_networks) == 0:
        network_arguments.update(connection_args)
        res = _neutron_module_call(
            'create_network', **network_arguments)['network']

        if res.get('name') == name:
            return _created(name, 'network', res['name'])

    elif len(existing_networks) > 1:
        LOG.error("More than one network found with the name: {0}".format(
                  name))

    elif len(existing_networks) == 1:
        existing_network = existing_networks[0]
        LOG.info('CONNECTION STRINGS' + str(connection_args))
        LOG.info('existing ' + str(existing_network))
        LOG.info('new ' + str(network_arguments))
        existing_network = dict((key.replace(':', '_', 1), value)
                                for key, value in
                                existing_network.iteritems())
        # generate differential
        diff = dict((key, value) for key, value in network_arguments.iteritems()
                    if existing_network.get(key, None) != value)
        if diff:
            # update the changes
            network_arguments = diff.copy()
            network_arguments.update(connection_args)
            try:
                LOG.debug('updating network {0} with changes {1}'.format(
                    name, str(diff)))
                _neutron_module_call('update_network',
                                     existing_network['id'],
                                     **network_arguments)
                changes_dict = _created(name, 'network', diff)
                changes_dict['comment'] = '{1} {0} updated'.format(name, 'network')
                return changes_dict
            except:
                LOG.error('Could not update network {0}'.format(name))
                return _update_failed(name, 'network')
        return _no_change(name, 'network')
    return _create_failed(name, 'network')


@_test_call
def network_absent(name, network_id=None, profile=None, endpoint_type=None):
    connection_args = _auth(profile, endpoint_type)
    identifier = network_id or name
    _neutron_module_call(
        'delete_network', identifier, **connection_args)
    return _absent(identifier, 'network')


@_test_call
def subnet_present(name,
                   network_name=None,
                   network_id=None,
                   tenant=None,
                   cidr=None,
                   ip_version=4,
                   enable_dhcp=True,
                   allocation_pools=None,
                   gateway_ip=None,
                   dns_nameservers=None,
                   host_routes=None,
                   profile=None,
                   endpoint_type=None):
    '''
    Ensure that the neutron subnet is present with the specified properties.
    name
        The name of the subnet to manage
    '''
    if network_name is None and network_id is None:
        LOG.error("Network identificator name or uuid should be provided.")
        return _create_failed(name, 'subnet')

    connection_args = _auth(profile, endpoint_type)
    tenant_id = _get_tenant_id(tenant_name=tenant, **connection_args)

    existing_subnets = _neutron_module_call(
        'list_subnets', tenant_id=tenant_id, name=name,
         **connection_args)['subnets']

    subnet_arguments = _get_non_null_args(
        name=name,
        cidr=cidr,
        ip_version=ip_version,
        enable_dhcp=enable_dhcp,
        allocation_pools=allocation_pools,
        gateway_ip=gateway_ip,
        dns_nameservers=dns_nameservers,
        host_routes=host_routes)

    if network_id is None and network_name:
        existing_networks = _neutron_module_call(
            'list_networks', tenant_id=tenant_id, name=network_name,
            **connection_args)['networks']
        if len(existing_networks) == 0:
            LOG.error("Can't find network with name: {0}".format(network_name))
        elif len(existing_networks) == 1:
            network_id = existing_networks[0]['id']
        elif len(existing_networks) > 1:
            LOG.error("Multiple networks with name: {0} found.".format(
                      network_name))

    if network_id is None:
        return _create_failed(name, 'subnet')

    subnet_arguments['network_id'] = network_id

    if len(existing_subnets) == 0:
        subnet_arguments.update(connection_args)
        res = _neutron_module_call('create_subnet', tenant_id=tenant_id,
                                   **subnet_arguments)['subnet']
        if res.get('name') == name:
            return _created(name, 'subnet', res)
        return _create_failed(name, 'subnet')

    elif len(existing_subnets) == 1:
        existing_subnet = existing_subnets[0]

        # create differential
        LOG.error('existing ' + str(existing_subnet))
        LOG.error('new ' + str(subnet_arguments))
        diff = dict((key, value) for key, value in subnet_arguments.iteritems()
                    if existing_subnet.get(key, None) != value)
        if not diff:
            return _no_change(name, 'subnet')

        # update the changes
        subnet_arguments = diff.copy()
        subnet_arguments.update(connection_args)
        try:
            LOG.debug('updating subnet {0} with changes {1}'.format(
                name, str(diff)))
            _neutron_module_call('update_subnet',
                                 existing_subnet['id'],
                                 **subnet_arguments)
            changes_dict = _created(name, 'subnet', diff)
            changes_dict['comment'] = '{1} {0} updated'.format(name, 'subnet')
            return changes_dict
        except:
            LOG.error('Could not update subnet {0}'.format(name))
            return _update_failed(name, 'subnet')

    elif len(existing_subnets) > 1:
        LOG.error("Multiple subnets with name: {0} found".format(
                  name))
        return _create_failed(name, 'network')


@_test_call
def subnet_absent(name, subnet_id=None, profile=None, endpoint_type=None):
    connection_args = _auth(profile, endpoint_type)
    identifier = subnet_id or name
    _neutron_module_call(
        'delete_subnet', identifier, **connection_args)
    return _absent(name, 'subnet')


@_test_call
def router_present(name=None,
                   tenant=None,
                   gateway_network=None,
                   interfaces=None,
                   admin_state_up=True,
                   profile=None,
                   endpoint_type=None):
    '''
    Ensure that the neutron router is present with the specified properties.
    name
        The name of the subnet to manage
    gateway_network
        The network that would be the router's default gateway
    interfaces
        list of subnets the router attaches to
    '''
    connection_args = _auth(profile, endpoint_type)
    tenant_name = tenant
    try:
        tenant_id = __salt__['keystone.tenant_get'](
            name=tenant_name, **connection_args)[tenant_name]['id']
    except:
        tenant_id = None
        LOG.debug('Cannot get the tenant id. User {0} is not an admin.'.format(
            connection_args['connection_user']))
    existing_router = _neutron_module_call(
        'list_routers', name=name, **connection_args)
    if not existing_router:
        _neutron_module_call('create_router', name=name, tenant_id=tenant_id, admin_state_up=admin_state_up, **connection_args)
        created_router = _neutron_module_call(
            'list_routers', name=name, **connection_args)
        if created_router:
            router_id = created_router[name]['id']
            network = _neutron_module_call(
                'list_networks', name=gateway_network, **connection_args)
            gateway_network_id = network[gateway_network]['id']
            _neutron_module_call('router_gateway_set',
                                 router_id=router_id,
                                 external_gateway=gateway_network_id,
                                 **connection_args)
            for interface in interfaces:
                subnet = _neutron_module_call(
                    'list_subnets', name=interface, **connection_args)
                subnet_id = subnet[interface]['id']
                _neutron_module_call('router_add_interface',
                                     router_id=router_id,
                                     subnet_id=subnet_id,
                                     **connection_args)
            return _created(name,
                            'router',
                            _neutron_module_call('list_routers',
                                                 name=name,
                                                 **connection_args))
        return _create_failed(name, 'router')

    router_id = existing_router[name]['id']
    existing_router = existing_router[name]
    diff = {}
    if ( admin_state_up == True or admin_state_up == False ) and existing_router['admin_state_up'] != admin_state_up:
        diff.update({'admin_state_up': admin_state_up})
    if gateway_network:
        network = _neutron_module_call(
            'list_networks', name=gateway_network, **connection_args)
        gateway_network_id = network[gateway_network]['id']
        if not existing_router['external_gateway_info'] and not existing_router['external_gateway_info'] == None:
            if existing_router['external_gateway_info']['network_id'] != gateway_network_id:
                diff.update({'external_gateway_info': {'network_id': gateway_network_id}})
        elif not existing_router['external_gateway_info'] == None:
            if not 'network_id' in existing_router['external_gateway_info'] or existing_router['external_gateway_info']['network_id'] != gateway_network_id:
                diff.update({'external_gateway_info': {'network_id': gateway_network_id}})
    if diff:
        # update the changes
        router_args = diff.copy()
        router_args.update(connection_args)
        try:
            _neutron_module_call('update_router', existing_router['id'], **router_args)
            changes_dict = _created(name, 'router', diff)
            changes_dict['comment'] = 'Router {0} updated'.format(name)
            return changes_dict
        except:
            LOG.exception('Router {0} could not be updated'.format(name))
            return _update_failed(name, 'router')
    return _no_change(name, 'router')


def floatingip_present(name=None,
                       tenant_name=None,
                       subnet=None,
                       tenant=None,
                       network=None,
                       port_id=None,
                       fip_exists=False,
                       profile=None,
                       endpoint_type=None):
    '''
    Ensure that the floating ip address is present for an instance
    '''
    instance_id = __salt__['novang.server_get'](name=name, tenant_name=tenant_name, profile=profile)
    subnet_name = subnet
    connection_args = _auth(profile, endpoint_type)
    existing_subnet = _neutron_module_call(
        'list_subnets', name=subnet_name, **connection_args)
    subnet_id = existing_subnet[subnet_name]['id']

    ret = {}
    existing_ports = _neutron_module_call(
        'list_ports', **connection_args)
    existing_floatingips = _neutron_module_call(
        'list_floatingips', **connection_args)

    tenant = __salt__['keystone.tenant_get'](name=tenant_name, profile=profile, **connection_args)
    tenant_id = tenant[tenant_name]['id']
    existing_network = _neutron_module_call(
            'list_networks', name=network, **connection_args)
    floating_network_id = existing_network[network]['id']

    for key, value in existing_ports.iteritems():
        try:
            if value['fixed_ips'][0]['subnet_id'] == subnet_id and value['device_id'] == instance_id:
                port_id=value['id']
        except:
            pass
    for key, value in existing_floatingips.iteritems():
        try:
            if value['floating_network_id'] == floating_network_id and value['port_id'] == port_id and value['tenant_id'] == tenant_id:
                fip_exists = True
                break
        except:
            pass

    if fip_exists == False:
        for key, value in existing_ports.iteritems():
            try:
                if value['fixed_ips'][0]['subnet_id'] == subnet_id and value['device_id'] == instance_id:
                    ret = _neutron_module_call('create_floatingip', floating_network_id=floating_network_id, port_id=value['id'], tenant_id=tenant_id, **connection_args)
            except:
                pass
        return _created('port', 'floatingip', ret)
    else:
        return _no_change('for instance {0}'.format(name), 'floatingip')


def security_group_present(name=None,
                           tenant=None,
                           description=None,
                           rules=[],
                           profile=None,
                           endpoint_type=None):
    '''
    Ensure that the security group is present with the specified properties.
    name
        The name of the security group
    description
        The description of the security group
    rules
        list of rules to be added to the given security group
    '''
    # If the user is an admin, he's able to see the security groups from
    # other tenants. In this case, we'll use the tenant id to get an existing
    # security group.
    connection_args = _auth(profile, endpoint_type)
    tenant_name = tenant
    try:
        tenant_id = __salt__['keystone.tenant_get'](
            name=tenant_name, **connection_args)[tenant_name]['id']
    except:
        tenant_id = None
        LOG.debug('Cannot get the tenant id. User {0} is not an admin.'.format(
            connection_args['connection_user']))
    if tenant_id:
        security_group = _neutron_module_call(
            'list_security_groups', name=name, tenant_id=tenant_id,
            **connection_args)
    else:
        security_group = _neutron_module_call(
            'list_security_groups', name=name, **connection_args)

    if not security_group:
        # Create the security group as it doesn't exist already.
        security_group_id = _neutron_module_call('create_security_group',
                                                 name=name,
                                                 description=description,
                                                 tenant_id=tenant_id,
                                                 **connection_args)
    else:
        security_group_id = security_group[name]['id']

    # Set the missing rules attributes (in case the user didn't specify them
    # in pillar) to some default values.
    rules_attributes_defaults = {
        'direction': 'ingress',
        'ethertype': 'IPv4',
        'protocol': 'TCP',
        'port_range_min': None,
        'port_range_max': None,
        'remote_ip_prefix': None
    }
    for rule in rules:
        for attribute in rules_attributes_defaults.keys():
            if not rule.has_key(attribute):
                rule[attribute] = rules_attributes_defaults[attribute]

    # Remove all the duplicates rules given by the user in pillar.
    unique_rules = []
    for rule in rules:
        if rule not in unique_rules:
            unique_rules.append(rule)

    # Get the existing security group rules.
    existing_rules = _neutron_module_call(
        'list_security_groups',
        id=security_group_id,
        **connection_args)[name]['security_group_rules']

    new_rules = {}
    for rule in unique_rules:
        rule_found = False
        for existing_rule in existing_rules:
            attributes_match = True
            # Compare the attributes of the existing security group rule with
            # the attributes of the rule that we want to add.
            for attribute in rules_attributes_defaults.keys():
                existing_attribute = '' if not existing_rule[attribute] \
                                        else str(existing_rule[attribute]).lower()
                attribute = '' if not rule[attribute] \
                               else str(rule[attribute]).lower()
                if existing_attribute != attribute:
                    attributes_match = False
                    break
            if attributes_match:
                rule_found = True
                break
        if rule_found:
            # Skip adding the rule as it already exists.
            continue
        rule_index = len(new_rules) + 1
        new_rules.update({'Rule {0}'.format(rule_index): rule})
        _neutron_module_call('create_security_group_rule',
                             security_group_id=security_group_id,
                             direction=rule['direction'],
                             ethertype=rule['ethertype'],
                             protocol=rule['protocol'],
                             port_range_min=rule['port_range_min'],
                             port_range_max=rule['port_range_max'],
                             remote_ip_prefix=rule['remote_ip_prefix'],
                             tenant_id=tenant_id,
                             **connection_args)

    if not security_group:
        # The security group didn't exist. It was created and specified
        # rules were added to it.
        security_group = _neutron_module_call('list_security_groups',
                                              id=security_group_id,
                                              **connection_args)[name]
        return _created(name, 'security_group', security_group)
    if len(new_rules) == 0:
        # Security group already exists and specified rules are already
        # present.
        return _no_change(name, 'security_group')
    # Security group already exists, but the specified rules were added to it.
    return _updated(name, 'security_group', {'New Rules': new_rules})

def _created(name, resource, resource_definition):
    changes_dict = {'name': name,
                    'changes': resource_definition,
                    'result': True,
                    'comment': '{0} {1} created'.format(resource, name)}
    return changes_dict

def _updated(name, resource, resource_definition):
    changes_dict = {'name': name,
                    'changes': resource_definition,
                    'result': True,
                    'comment': '{0} {1} updated'.format(resource, name)}
    return changes_dict

def _no_change(name, resource, test=False):
    changes_dict = {'name': name,
                    'changes': {},
                    'result': True}
    if test:
        changes_dict['comment'] = \
            '{0} {1} will be {2}'.format(resource, name, test)
    else:
        changes_dict['comment'] = \
            '{0} {1} is in correct state'.format(resource, name)
    return changes_dict


def _deleted(name, resource, resource_definition):
    changes_dict = {'name': name,
                    'changes': {},
                    'comment': '{0} {1} removed'.format(resource, name),
                    'result': True}
    return changes_dict


def _absent(name, resource):
    changes_dict = {'name': name,
                    'changes': {},
                    'comment': '{0} {1} not present'.format(resource, name),
                    'result': True}
    return changes_dict


def _delete_failed(name, resource):
    changes_dict = {'name': name,
                    'changes': {},
                    'comment': '{0} {1} failed to delete'.format(resource,
                                                                 name),
                    'result': False}
    return changes_dict

def _create_failed(name, resource):
    changes_dict = {'name': name,
                    'changes': {},
                    'comment': '{0} {1} failed to create'.format(resource,
                                                                 name),
                    'result': False}
    return changes_dict

def _update_failed(name, resource):
    changes_dict = {'name': name,
                    'changes': {},
                    'comment': '{0} {1} failed to update'.format(resource,
                                                                 name),
                    'result': False}
    return changes_dict


def _get_non_null_args(**kwargs):
    '''
    Return those kwargs which are not null
    '''
    return dict((key, value,) for key, value in kwargs.iteritems()
                if value is not None)
