# -*- 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__['keystoneng.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,
                    dns_domain=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,
        dns_domain=dns_domain)

    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__['keystoneng.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)["networks"]
            #TODO test for more networks
            gateway_network_id = network[0]['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)["subnets"]
                subnet_id = subnet[0]['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)["networks"]
        gateway_network_id = network[0]['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)["subnets"]
    subnet_id = existing_subnet[0]['id']

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

    tenant = __salt__['keystoneng.tenant_get'](name=tenant_name, **connection_args)
    tenant_id = tenant[tenant_name]['id']
    existing_network = _neutron_module_call(
            'list_networks', name=network, **connection_args)["networks"]
    floating_network_id = existing_network[0]['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='',
                           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__['keystoneng.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 port_present(network_name, profile=None, endpoint_type=None, name=None,
                 tenant=None, description='', fixed_ips=None, device_id=None,
                 device_owner=None, binding_host_id=None, admin_state_up=True,
                 mac_address=None, vnic_type=None, binding_profile=None,
                 security_groups=None, extra_dhcp_opt=None, qos_policy=None,
                 allowed_address_pair=None, dns_name=None):
    """
    Ensure the port is present with specified parameters.

    :param network_name: Name of the network to create port in
    :param profile: Authentication profile
    :param endpoint_type: Endpoint type
    :param name: Name of this port
    :param tenant: Tenant in which the port should be created, avaiable for
                   admin only.
    :param description: Port description
    :param fixed_ips: Desired IP and/or subnet for this port:
                      subnet_id=<name_or_id>,ip_address=<ip>.
    :param device_id: Device ID of this port
    :param device_owner: Device owner of this port
    :param binding_host_id: he ID of the host where the port resides.
    :param admin_state_up: Admin state of this port
    :param mac_address: MAC address of this port
    :param vnic_type: VNIC type for this port
    :param binding_profile: Custom data to be passed as binding:profile
    :param security_groups: Security group associated with the port
    :param extra_dhcp_opt: Extra dhcp options to be assigned to this port:
                           opt_na me=<dhcp_option_name>,opt_value=<value>,
                                     ip_version={4, 6}
    :param qos_policy: ID or name of the QoS policy that shouldbe attached to
                       the resource
    :param allowed_address_pair: ip_address=IP_ADDR|CIDR[,mac_address=MAC_ADDR]
                                 Allowed address pair associated with the port.
                                 "ip_address" parameter is required. IP address
                                 or CIDR can be specified for "ip_address".
                                 "mac_address" parameter is optional.
    :param dns_name: Assign DNS name to the port (requires DNS integration
                     extension)
    """

    connection_args = _auth(profile, endpoint_type)
    tenant_id = _get_tenant_id(tenant_name=tenant, **connection_args)
    network_id = None
    port_exists = False

    port_arguments = _get_non_null_args(
        name=name, tenant_id=tenant_id, description=description,
        fixed_ips=fixed_ips, device_id=device_id, device_owner=device_owner,
        admin_state_up=admin_state_up,
        mac_address=mac_address, vnic_type=vnic_type,
        binding_profile=binding_profile,
        extra_dhcp_opt=extra_dhcp_opt, qos_policy=qos_policy,
        allowed_address_pair=allowed_address_pair, dns_name=dns_name)
    if binding_host_id:
        port_arguments['binding:host_id'] = binding_host_id
    if security_groups:
        sec_group_list = []
        for sec_group_name in security_groups:
            security_group = _neutron_module_call(
                'list_security_groups', name=sec_group_name, **connection_args)
            if security_group:
                sec_group_list.append(security_group[sec_group_name]['id'])
        port_arguments['security_groups'] = sec_group_list

    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, 'port')

    port_arguments['network_id'] = network_id

    existing_ports = _neutron_module_call(
        'list_ports', network_id=network_id, tenant_id=tenant_id,
        **connection_args)

    if name:
        for key, value in existing_ports.iteritems():
            try:
                if value['name'] == name and value['tenant_id'] == tenant_id:
                    port_exists = True
                    break
            except KeyError:
                pass

    if not port_exists:
        port_arguments.update(connection_args)
        res = _neutron_module_call('create_port', **port_arguments)['port']
        if res['name'] == name:
            return _created(name, 'port', res)
        return _create_failed(name, 'port')
    else:
        return _no_change('for instance {0}'.format(name), 'port')


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)
