# -*- coding: utf-8 -*-
'''
Management of Neutron resources
===============================
:depends:   - neutronclient Python module
:configuration: See :py:mod:`salt.modules.neutron` for setup instructions.
.. code-block:: yaml
    neutron network present:
      neutron.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 _auth(profile=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
    }

    return kwargs

@_test_call
def network_present(name=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):
    '''
    Ensure that the neutron network is present with the specified properties.
    name
        The name of the network to manage
    '''
    tenant_name = tenant
    connection_args = _auth(profile)
    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_networks = _neutron_module_call(
        'list_networks', **connection_args)
    for network in existing_networks:
        if network.get(name) == name:
            existing_network = network
    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 not existing_network:
        network_arguments.update(connection_args)
        _neutron_module_call('create_network', **network_arguments)
        existing_networks = _neutron_module_call(
            'list_networks', **connection_args)
        for network in existing_networks:
            if network.get(name) == name:
                existing_network = network
        if existing_network:
            return _created(name, 'network', existing_network[name])
        return _update_failed(name, 'network')

    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[name].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.exception('Could not update network {0}'.format(name))
            return _update_failed(name, 'network')
    return _no_change(name, 'network')


@_test_call
def network_absent(name, profile=None):
    connection_args = _auth(profile)
    existing_network = _neutron_module_call(
        'list_networks', name=name, **connection_args)
    if existing_network:
        _neutron_module_call(
            'delete_network', existing_network[name]['id'], **connection_args)
        if _neutron_module_call('list_networks', name=name, **connection_args):
            return _delete_failed(name, 'network')
        return _deleted(name, 'network', existing_network[name])
    return _absent(name, 'network')


@_test_call
def subnet_present(name=None,
                   tenant=None,
                   network=None,
                   cidr=None,
                   ip_version=4,
                   enable_dhcp=True,
                   allocation_pools=None,
                   gateway_ip=None,
                   dns_nameservers=None,
                   host_routes=None,
                   profile=None):
    '''
    Ensure that the neutron subnet is present with the specified properties.
    name
        The name of the subnet to manage
    '''
    connection_args = _auth(profile)
    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_subnet = _neutron_module_call(
        'list_subnets', tenant_id=tenant_id, name=name, **connection_args)
    subnet_arguments = _get_non_null_args(
        name=name,
        network=network,
        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)
    # replace network with network_id
    if 'network' in subnet_arguments:
        network = subnet_arguments.pop('network', None)
        existing_network = _neutron_module_call(
            'list_networks', tenant_id=tenant_id, name=network, **connection_args)
        if existing_network:
            subnet_arguments['network_id'] = existing_network[network]['id']
    if not existing_subnet:
        subnet_arguments.update(connection_args)
        _neutron_module_call('create_subnet', tenant_id=tenant_id, **subnet_arguments)
        existing_subnet = _neutron_module_call(
            'list_subnets', tenant_id=tenant_id, name=name, **connection_args)
        if existing_subnet:
            return _created(name, 'subnet', existing_subnet[name])
        return _update_failed(name, 'subnet')
    # change from internal representation
    existing_subnet = existing_subnet[name]
    # 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 diff:
        # 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.exception('Could not update subnet {0}'.format(name))
            return _update_failed(name, 'subnet')
    return _no_change(name, 'subnet')


@_test_call
def subnet_absent(name, profile=None):
    connection_args = _auth(profile)
    existing_subnet = _neutron_module_call(
        'list_subnets', tenant_id=tenant_id, name=name, **connection_args)
    if existing_subnet:
        _neutron_module_call(
            'delete_subnet', existing_subnet[name]['id'], **connection_args)
        if _neutron_module_call('list_subnets', name=name, **connection_args):
            return _delete_failed(name, 'subnet')
        return _deleted(name, 'subnet', existing_subnet[name])
    return _absent(name, 'subnet')
    return _absent(name, 'network')


@_test_call
def router_present(name=None,
                   tenant=None,
                   gateway_network=None,
                   interfaces=None,
                   admin_state_up=True,
                   profile=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)
    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):
    '''
    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)
    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):
    '''
    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)
    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)