#
# Copyright (c) 2012,2013 Big Switch Networks, Inc.
#
# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
#
# 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 collections
import urllib
import error
import json
import modi
import utif
import url_cache

#
# json based on non model based query
#

def rest_to_model_init(bs, modi):
    global sdnsh, mi

    sdnsh = bs
    mi = modi

#
# --------------------------------------------------------------------------------

def check_rest_result(result, message = None):
    if isinstance(result, collections.Mapping):
        error_type = result.get('error_type')
        if error_type:
            raise error.CommandRestError(result, message)


#
# --------------------------------------------------------------------------------

def get_model_from_url(obj_type, data):
    """
    Intended to be used as a conversion tool, to provide a way
    to move model requests to specific url requests
    """

    onos = 1
    startswith = '__startswith'
    data = dict(data)

    if mi.obj_type_has_model(obj_type):
        print "MODEL_URL: %s not supported" % obj_type
        return []
    #
    # save sort field
    sort = data.get('orderby', None)
    if sort:
        del data['orderby']

    obj_type_url = mi.obj_type_has_url(obj_type)
    url = "http://%s/rest/v1/" % sdnsh.controller + obj_type_url

    # for the devices query, be sensitive to the types of queries
    # since the devices query doesn't understand the relationship
    # between the vlan=='' for address_space == 'default'.
    if obj_type_url == 'device':
        if 'vlan' in data and data['vlan'] == '':
            del data['vlan']

    # data items need to be included into the query.
    if data:
        url += '?'
        url += urllib.urlencode(data)
    if sdnsh.description:   # description debugging
        print "get_model_from_url: request ", obj_type, data, url
    #
    # cache small, short time results
    entries = url_cache.get_cached_url(url)
    if entries != None:
        if sdnsh.description:   # description debugging
            print 'get_model_from_url: using cached result for ', url
    else:
        try:
            result = sdnsh.store.rest_simple_request(url)
            check_rest_result(result)
            entries = json.loads(result)
        except Exception, e:
            if sdnsh.description:   # description debugging
                print "get_model_from_url: failed request %s: '%s'" % (url, e)
            entries = []
        
        url_cache.save_url(url, entries)

    key = mi.pk(obj_type)

    # convert specific types XXX need better generic mechanism
    result = []
    if obj_type == 'host-attachment-point':
        for entry in entries:
            # it is possible for multiple mac's to appear here 
            # as long as a single ip is associated with the device.
            if len(entry['mac']) > 1:
                raise error.CommandInternalError("host (attachment point): >1 mac")
            mac = entry['mac'][0]
            aps = entry['attachmentPoint']
            lastseen = entry['lastSeen']
            for ap in aps:
                status = ap.get('errorStatus', '')
                if status == None:
                    status = ''
                if len(entry['vlan']) == 0:
                    result.append({'id'           : mac + '|' + ap['switchDPID'] +
                                                          '|' + str(ap['port']),
                                   'mac'          : mac,
                                   'switch'       : ap['switchDPID'],
                                   'ingress-port' : ap['port'],
                                   'status'       : status,
                                   'last-seen'    : lastseen,
                                   'address-space': entry['entityClass'],
                                   })
                else:
                    for vlan in entry['vlan']:
                        result.append({'id'           : mac + '|' + ap['switchDPID'] +
                                                              '|' + str(ap['port']),
                                       'mac'          : mac,
                                       'vlan'         : vlan,
                                       'switch'       : ap['switchDPID'],
                                       'ingress-port' : ap['port'],
                                       'status'       : status,
                                       'last-seen'    : lastseen,
                                       'address-space': entry['entityClass'],
                                       })
    elif obj_type == 'host-network-address':

        for entry in entries:
            if len(entry['mac']) > 1:
                raise error.CommandInternalError("host (network-address): >1 mac")
            mac = entry['mac'][0]
            ips = entry['ipv4']
            lastseen = entry['lastSeen']
            for ip in ips:
                if len(entry['vlan']) == 0:
                    result.append({'id'            : mac + '|' + ip,
                                   'mac'           : mac,
                                   'ip-address'    : ip,
                                   'address-space' : entry['entityClass'],
                                   'last-seen'     : lastseen })
                else:
                    for vlan in entry['vlan']:
                        result.append({'id'            : mac + '|' + ip,
                                       'mac'           : mac,
                                       'vlan'          : vlan,
                                       'ip-address'    : ip,
                                       'address-space' : entry['entityClass'],
                                       'last-seen'     : lastseen })
    elif obj_type == 'host':
        # For host queries, the device manager returns 'devices' which
        # match specific criteria, for example, if you say ipv4 == 'xxx',
        # the device which matches that criteris is returned.  However,
        # there may be multiple ip addresses associated.
        #
        # this means that two different groups of values for these
        # entities are returned.  fields like 'ipv4' is the collection
        # of matching values, while 'ips' is the complee list.
        # 'switch', 'port' are the match values, while 'attachment-points'
        # is the complete list.
        #

        ip_match = data.get('ipv4')
        ip_prefix = data.get('ipv4__startswith')

        dpid_match = data.get('dpid')
        dpid_prefix = data.get('dpid__startswith')

        port_match = data.get('port')
        port_prefix = data.get('port__startswith')

        address_space_match = data.get('address-space')
        address_space_prefix = data.get('address-space__startswith')

        for entry in entries:
            if len(entry['mac']) > 1:
                raise error.CommandInternalError("host: >1 mac")
            mac = entry['mac'][0]
            lastseen = entry['lastSeen']

            if not ip_match and not ip_prefix:
                ipv4 = entry['ipv4']
            elif ip_match:
                ipv4 = [x for x in entry['ipv4'] if x == ip_match]
            elif ip_prefix:
                ipv4 = [x for x in entry['ipv4'] if x.startswith(ip_prefix)]

            ips = None
            if len(entry['ipv4']):
                ips = [{'ip-address' : x, 'last-seen' : lastseen}
                        for x in entry['ipv4'] ]

            aps = None
            switch = []
            port = []

            dpid_match = entry.get('dpid')

            if len(entry['attachmentPoint']):
                aps = [{'switch' : x['switchDPID'], 'ingress-port' : x['port'] }
                       for x in entry['attachmentPoint']]

                if not dpid_match and not dpid_prefix:
                    switch = [x['switchDPID'] for x in entry['attachmentPoint']]
                elif dpid_match:
                    switch = [x['switchDPID'] for x in entry['attachmentPoint']
                              if x['switchDPID'] == dpid_match]
                elif dpid_prefix:
                    switch = [x['switchDPID'] for x in entry['attachmentPoint']
                              if x['switchDPID'].startswith(dpid_prefix)]
                
                if not port_match and not port_prefix:
                    port = [x['port'] for x in entry['attachmentPoint']]
                elif port_match:
                    port = [x['port'] for x in entry['attachmentPoint']
                            if x['port'] == port_match]
                elif port_prefix:
                    port = [x['port'] for x in entry['attachmentPoint']
                            if x['port'].startswith(port_prefix)]

            address_space = entry['entityClass']
            dhcp_client_name = entry.get('dhcpClientName', '')
            if address_space_match and address_space != address_space_match:
                continue
            if address_space_prefix and not address_space.startswith(address_space_prefix):
                continue

            if len(entry['vlan']) == 0:
                id = '%s||%s' % (address_space, mac)
                result.append({'id'                : id,
                               'mac'               : mac,
                               'ips'               : ips,
                               'ipv4'              : ipv4,
                               'attachment-points' : aps,
                               'dpid'              : switch,
                               'port'              : port,
                               'address-space'     : address_space,
                               'dhcp-client-name'  : dhcp_client_name,
                               'last-seen'         : lastseen})
            else:
                for vlan in entry['vlan']:
                    if address_space != 'default':
                        id = '%s||%s' % (address_space, mac)
                    else:
                        id = '%s|%s|%s' % (address_space, vlan, mac)
                    result.append({'id'                : id,
                                   'mac'               : mac,
                                   'vlan'              : vlan,
                                   'ips'               : ips,
                                   'ipv4'              : ipv4,
                                   'attachment-points' : aps,
                                   'dpid'              : switch,
                                   'port'              : port,
                                   'address-space'     : address_space,
                                   'dhcp-client-name'  : dhcp_client_name,
                                   'last-seen'         : lastseen})

        # Also need to add hostConfig entries.
        if not mi.obj_type_has_model('host-config'):
            raise error.CommandInternalError("host-config: not served via model")
        host_config = sdnsh.rest_query_objects('host-config', data)
        if sdnsh.description:   # description debugging
            print "get_model_from_url: adding host-config ", data, host_config
        known_ids = [x['id'] for x in result]

        for hc in host_config:
            id = hc['id']
            if id not in known_ids:
                # be sensitive to search fields:
                query_match = True
                if len(data):
                    for (d, dv) in data.items():
                        # other ops aside from '='?
                        if d.endswith(startswith):
                            fn = d[:-len(startswith)]
                            if not fn in hc or not hc[fn].startswith(dv):
                                query_match = False
                        elif (not d in hc) or dv != hc[d]:
                            query_match = False
                            break
                            
                if query_match:
                    hc['attachment-points'] = None
                    hc['dpid'] = None
                    hc['ips'] = None
                    hc['last-seen'] = None
                    result.append(hc)

    elif obj_type == 'vns-interface':
        for entry in entries:
            vns = entry['parentVNS']['name']
            rule = entry['parentRule']
            rule_name = 'default'
            if rule and 'name' in rule:
                rule_name = rule['name']

            result.append({ key            : vns + '|' + entry['name'],
                           'vns'           : vns,
                           'address-space' : entry['parentVNS']['addressSpaceName'],
                           'interface'     : entry['name'],
                           'rule'          : rule_name,
                           'last-seen'     : entry['lastSeen'],
                          })

        # also need to add vns-interface-config
        if not mi.obj_type_has_model('vns-interface-config'):
            raise error.CommandInternalError("vns-interface-config: not service via model")
        vns_intf_config = sdnsh.rest_query_objects('vns-interface-config', data)
        known_vns_intfs = [x[key] for x in result]
        for vns_intf in vns_intf_config:
            if not vns_intf[key] in known_vns_intfs:
                vns_intf['rule'] = 'default'
                result.append(vns_intf)

    elif obj_type == 'host-vns-interface':

        # mac matching works for the request

        vns_match = data.get('vns')
        vns_prefix = data.get('vns__startswith')

        for entry in entries:
            device = entry['device']
            if len(device['mac']) > 1:
                raise error.CommandInternalError("host (vns-interface): >1 mac")

            device_last_seen = device['lastSeen']
            address_space = device['entityClass']
            mac = device['mac'][0]          # currently, should only be one

            ips = None
            if len(device['ipv4']):
                ips = [{'ip-address' : x, 'last-seen' : device_last_seen}
                        for x in device['ipv4'] ]

            vlans = device.get('vlan', [])   # currently, should only be one
            if len(vlans) == 0:              # iterate once when list is empty
                vlans = [ '' ]

            aps = None
            if len(device['attachmentPoint']):
                aps = [{'switch' : x['switchDPID'], 'ingress-port' : x['port'] }
                       for x in device['attachmentPoint']]

            for iface in entry.get('iface', []):
                vns = iface['parentVNS']['name']
                last_seen = iface['lastSeen']
                if vns_match and vns_match != vns:
                    continue
                if vns_prefix and not vns.startswith(vns_prefix):
                    continue

                for vlan in vlans: # there's supposed to only be at most one vlan.
                    if address_space != 'default' or type(vlan) != int:
                        host = '%s||%s' % (address_space, mac)
                    else:
                        host = '%s|%s|%s' % (address_space, vlan, mac)

                    result.append({key             : mac + '|' + vns + '|' + iface['name'],
                                   'host'          : host,
                                   'mac'           : mac,
                                   'vlan'          : vlan,
                                   'address-space' : address_space,
                                   'ips'           : ips,
                                   'attachment-points' : aps,
                                   'vns'               : vns,
                                   'interface'         : vns + '|' + iface['name'],
                                   'last-seen'         : device_last_seen})
    elif obj_type == 'switches':
        switch_match = data.get('dpid')
        switch_prefix = data.get('dpid__startswith')

        # this synthetic obj_type's name is 'switches' in an attempt
        # to disabigutate it from 'class Switch'
        for entry in entries:
            if switch_match and switch_match != entry['dpid']:
                continue
            if switch_prefix and not entry['dpid'].startswith(switch_prefix):
                continue
            if onos == 1:
                result.append({
                   'dpid'                : entry['dpid'],
                   'connected-since'     : 0,
                   'ip-address'          : 0,
                })
            else:
                attrs = entry['attributes']
                actions = entry['actions']
                capabilities = entry['capabilities']
                inet_address = entry.get('inetAddress')
                ip_address = ''
                tcp_port = ''
                if inet_address:
                    # Current Java value looks like: /192.168.2.104:38420
                    inet_parts = inet_address.split(':')
                    ip_address = inet_parts[0][1:]
                    tcp_port = inet_parts[1]
    
                result.append({
                   'dpid'                : entry['dpid'],
                   'connected-since'     : entry['connectedSince'],
                   'ip-address'          : ip_address,
                   'tcp-port'            : tcp_port,
                   'actions'             : actions,
                   'capabilities'        : capabilities,
                   'dp-desc'             : attrs.get('DescriptionData', ''),
                   'fast-wildcards'      : attrs.get('FastWildcards', ''),
                   'supports-nx-role'    : attrs.get('supportsNxRole', ''),
                   'supports-ofpp-flood' : attrs.get('supportsOfppFlood', ''),
                   'supports-ofpp-table' : attrs.get('supportsOfppTable', ''),
                   'core-switch'         : False,
                })
        # now add switch-config

        switch_config = sdnsh.rest_query_objects('switch-config', data)
        known_dpids = dict([[x['dpid'], x] for x in result])

        if onos == 0:
            for sw in switch_config:
                dpid = sw['dpid']
                if not dpid in known_dpids:
                    # be sensitive to search fields:
                    query_match = True
                    if len(data):
                        for (d, dv) in data.items():
                            # other ops aside from '='?
                            if d.endswith(startswith):
                                fn = d[:-len(startswith)]
                                if not fn in sw or not sw[fn].startswith(dv):
                                    query_match = False
                            elif (not d in sw) or dv != sw[d]:
                                query_match = False
                                break
    
                    if query_match:
                        sw['ip-address'] = ''
                        sw['tcp-port'] = ''
                        sw['connected-since'] = ''
                        result.append(sw)
                else:
                    known_dpids[dpid].update(sw)
    elif obj_type == 'interfaces':

        # These are called interfaces because the primary
        # key is constructed with the interface name, not
        # the port number.

        # the 'switches' query to sdnplatform currently
        # doesn't support searching for the interface
        # names.  its done here instead

        switch_match = data.get('dpid')
        switch_prefix = data.get('dpid__startswith')

        name_match = data.get('portName')
        if name_match:
            name_match = name_match.lower()
        name_prefix = data.get('portName__startswith')
        if name_prefix:
            name_prefix = name_prefix.lower()

        # this synthetic obj_type's name is 'switches' in an attempt
        # to disabigutate it from 'class Switch'
        for entry in entries:
            dpid = entry['dpid']

            if switch_match and switch_match != dpid:
                continue
            if switch_prefix and not dpid.startswith(switch_prefix):
                continue

            for p in entry['ports']:
                if onos == 0:
                    portNumber = p['portNumber']
                    name = p['name']
                else:
                    portNumber = p['number']
                    name = 0

                if name_match and name.lower() != name_match:
                    continue
                if name_prefix and not name.lower().startswith(name_prefix):
                    continue
                if onos == 0:
                    result.append({
                                    'id'                 : '%s|%s' % (dpid,name),
                                    'portNumber'         : portNumber,
                                    'switch'             : dpid,
                                    'portName'           : p['name'],
                                    'config'             : p['config'],
                                    'state'              : p['state'],
                                    'advertisedFeatures' : p['advertisedFeatures'],
                                    'currentFeatures'    : p['currentFeatures'],
                                    'hardwareAddress'    : p['hardwareAddress'],
                                  })
                else:
                    result.append({
                                    'id'                 : '%s|%s' % (dpid,name),
                                    'portNumber'         : portNumber,
                                    'switch'             : dpid,
                                    'portName'           : 0,
                                    'config'             : 0,
                                    'state'              : p['state'],
                                    'advertisedFeatures' : 0,
                                    'currentFeatures'    : 0,
                                    'hardwareAddress'    : 0,
                                  })
                

    #
    # order the result
    if sort:
        if sort[0] == '-':
            sort = sort[1:]
            # decreasing
            if sdnsh.description:   # description debugging
                print "get_model_from_url: order decreasing ", sort
            result = sorted(result, key=lambda k:k.get(sort, ''),
                                    cmp=lambda x,y : cmp(y,x))
        else:
            # increasing
            if sdnsh.description:   # description debugging
                print "get_model_from_url: order increasing ", sort
            result = sorted(result, key=lambda k:k.get(sort, ''),
                                    cmp=lambda x,y : cmp(x,y))
    else:
        # use tail-integer on the entries
        if sdnsh.description:   # description debugging
            print "get_model_from_url: pk ordering ", key
        def sort_cmp(x,y):
            for (idx, x_v) in enumerate(x):
                c = cmp(utif.try_int(x_v), utif.try_int(y[idx]))
                if c != 0:
                    return c
            return 0
        result = sorted(result, key=lambda k:k.get(key, '').split('|'),
                                cmp=lambda x,y : cmp(utif.try_int(x),utif.try_int(y)))

    if sdnsh.description:   # description debugging
        print "get_model_from_url: result ", obj_type, url, len(result)

    return result


def validate_switch():
    """
    If /rest/v1/switches is cached, perform some validations on it.

    -- verify that the announced interfaces names are case insensitive
    -- verify the names only appear once
    """

    def duplicate_port(entry, name):
        dpid = entry['dpid']

        print 'Warning: switch %s duplicate interface names: %s' % (dpid, name)
        if sdnsh.debug_backtrace:
            for port in entry['ports']:
                if port['name'] == name:
                    print 'SWTICH %s:%s PORT %s' %  (entry, name, port)

    def not_case_sensitive(entry, name):
        dpid = entry['dpid']

        ports = {}
        for port in entry['ports']:
            if port['name'].lower() == name:
                ports[port['name']] = port
            
        print 'Warning: switch %s case insentive interface names: %s' % \
               (dpid, ' - '.join(ports.keys()))
        if sdnsh.debug_backtrace:
            for port in ports:
                print 'SWTICH %s PORT %s' % (dpid, port)

    url = "http://%s/rest/v1/switches" % sdnsh.controller
    entries = url_cache.get_cached_url(url)
    if entries:
        for entry in entries:
            dpid = entry['dpid']

            # verify that the port names are unique even when case
            # sensitive
            all_names = [p['name'] for p in entry['ports']]
            one_case_names = utif.unique_list_from_list([x.lower() for x in all_names])
            if len(all_names) != len(one_case_names):
                # Something is rotten, find out what.
                for (i, port_name) in enumerate(all_names):
                    # use enumerate to drive upper-triangle comparison
                    for other_name in all_names[i+1:]:
                        if port_name == other_name:
                            duplicate_port(entry, port_name)
                        elif port_name.lower() == other_name.lower():
                            not_case_sensitive(entry, port_name)
                    

