#
# Copyright 2017 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""
Convert loxi objects to openflow_13 messages and back.
"""
from copy import copy

from google.protobuf.descriptor import FieldDescriptor

import loxi.of13 as of13
from protobuf_to_dict import protobuf_to_dict, TYPE_CALLABLE_MAP
from voltha_protos import openflow_13_pb2 as pb2


type_callable_map = copy(TYPE_CALLABLE_MAP)
type_callable_map.update({
    FieldDescriptor.TYPE_STRING: str
})

def pb2dict(pb):
    """
    Convert protobuf to a dict of values good for instantiating
    loxi objects (or any other objects). We specialize the protobuf_to_dict
    library call with our modified decoders.
    :param pb: protobuf as loaded into Python
    :return: dict of values
    """
    return protobuf_to_dict(pb, type_callable_map)

def to_loxi(grpc_object):
    cls = grpc_object.__class__
    converter = to_loxi_converters[cls.__name__]
    return converter(grpc_object)

def to_grpc(loxi_object):
    cls = loxi_object.__class__
    converter = to_grpc_converters[cls]
    return converter(loxi_object)

def ofp_port_to_loxi_port_desc(pb):
    kw = pb2dict(pb)
    return of13.common.port_desc(**kw)

def ofp_port_status_to_loxi_port_status(pb):
    return of13.message.port_status(
        reason=pb.reason,
        desc=ofp_port_to_loxi_port_desc(pb.desc)
    )

def ofp_port_stats_to_loxi_port_stats(pb):
    kw = pb2dict(pb)
    return of13.port_stats_entry(**kw)

def make_loxi_field(oxm_field):
    assert oxm_field['oxm_class'] == pb2.OFPXMC_OPENFLOW_BASIC
    ofb_field = oxm_field['ofb_field']
    field_type = ofb_field.get('type', 0)

    if field_type == pb2.OFPXMT_OFB_ETH_TYPE:
        return (
            of13.oxm.eth_type(value=ofb_field['eth_type']))

    elif field_type == pb2.OFPXMT_OFB_IN_PORT:
        return (
            of13.oxm.in_port(value=ofb_field['port']))

    elif field_type == pb2.OFPXMT_OFB_IP_PROTO:
        return (
            of13.oxm.ip_proto(value=ofb_field['ip_proto']))

    elif field_type == pb2.OFPXMT_OFB_VLAN_VID:
        return (
            of13.oxm.vlan_vid(value=ofb_field['vlan_vid']))

    elif field_type == pb2.OFPXMT_OFB_VLAN_PCP:
        return (
            of13.oxm.vlan_pcp(value=ofb_field['vlan_pcp']))

    elif field_type == pb2.OFPXMT_OFB_IPV4_SRC:
        return (
            of13.oxm.ipv4_src(value=ofb_field['ipv4_src']))

    elif field_type == pb2.OFPXMT_OFB_IPV4_DST:
        return (
            of13.oxm.ipv4_dst(value=ofb_field['ipv4_dst']))

    elif field_type == pb2.OFPXMT_OFB_UDP_SRC:
        return (
            of13.oxm.udp_src(value=ofb_field['udp_src']))

    elif field_type == pb2.OFPXMT_OFB_UDP_DST:
        return (
            of13.oxm.udp_dst(value=ofb_field['udp_dst']))

    elif field_type == pb2.OFPXMT_OFB_METADATA:
        return (
            of13.oxm.metadata(value=ofb_field['table_metadata']))

    else:
        raise NotImplementedError(
            'OXM match field for type %s' % field_type)

def make_loxi_match(match):
    assert match.get('type', pb2.OFPMT_STANDARD) == pb2.OFPMT_OXM
    loxi_match_fields = []
    for oxm_field in match.get('oxm_fields', []):
        loxi_match_fields.append(make_loxi_field(oxm_field))
    return of13.match_v3(oxm_list=loxi_match_fields)


def make_loxi_action(a):
    if type(a) is not dict:
        a = pb2dict(a)

    typ = a.get('type', 0)

    if typ == pb2.OFPAT_OUTPUT:
        output_kws = a['output']
        return of13.action.output(**output_kws)

    elif typ == pb2.OFPAT_POP_VLAN:
        return of13.action.pop_vlan()

    elif typ == pb2.OFPAT_PUSH_VLAN:
        push_vlan_kws = a['push']
        return of13.action.push_vlan(**push_vlan_kws)

    elif typ == pb2.OFPAT_SET_FIELD:
        loxi_field = make_loxi_field(a['set_field']['field'])
        return of13.action.set_field(loxi_field)

    elif typ == pb2.OFPAT_GROUP:
        group_kws = a['group']
        return of13.action.group(**group_kws)

    else:
        raise NotImplementedError(
            'Action decoder for action OFPAT_* %d' % typ)


def ofp_flow_stats_to_loxi_flow_stats(pb):
    kw = pb2dict(pb)

    def make_loxi_instruction(inst):
        type = inst['type']
        if type == pb2.OFPIT_APPLY_ACTIONS:
            return of13.instruction.apply_actions(
                actions=[make_loxi_action(a)
                         for a in inst['actions']['actions']])
        elif type == pb2.OFPIT_CLEAR_ACTIONS:
            return of13.instruction.clear_actions()
        elif type == pb2.OFPIT_GOTO_TABLE:
            return of13.instruction.goto_table(
                table_id=inst['goto_table']['table_id'])
        elif type == pb2.OFPIT_WRITE_ACTIONS:
            return of13.instruction.write_actions(
                actions=[make_loxi_action(a)
                         for a in inst['actions']['actions']])
        elif type == pb2.OFPIT_WRITE_METADATA:
            if 'metadata' in inst['write_metadata']:
                return of13.instruction.write_metadata(
                        metadata=inst['write_metadata']['metadata'])
            else:
                return of13.instruction.write_metadata(0)
        elif type == pb2.OFPIT_METER:
            return of13.instruction.meter(
                meter_id=inst['meter']['meter_id'])
        else:
            raise NotImplementedError('Instruction type %d' % type)

    kw['match'] = make_loxi_match(kw['match'])
    # if the flow action is drop, then the instruction is not found in the dict
    if 'instructions' in kw:
        kw['instructions'] = [make_loxi_instruction(i) for i in kw['instructions']]
    del kw['id']
    return of13.flow_stats_entry(**kw)


def ofp_packet_in_to_loxi_packet_in(pb):
    packet_in = of13.message.packet_in(
        buffer_id=pb.buffer_id,
        reason=pb.reason,
        table_id=pb.table_id,
        cookie=pb.cookie,
        match=make_loxi_match(pb2dict(pb.match)),
        data=pb.data
    )
    return packet_in

def ofp_group_desc_to_loxi_group_desc(pb):
    return of13.group_desc_stats_entry(
        group_type=pb.type,
        group_id=pb.group_id,
        buckets=[to_loxi(bucket) for bucket in pb.buckets])


def ofp_group_stats_to_loxi_group_stats(pb):
    return of13.group_stats_entry(
        group_id=pb.group_id,
        ref_count=pb.ref_count,
        packet_count=pb.packet_count,
        byte_count=pb.byte_count,
        duration_sec=pb.duration_sec,
        duration_nsec=pb.duration_nsec,
        bucket_stats=[to_loxi(bstat) for bstat in pb.bucket_stats])


def ofp_bucket_counter_to_loxy_bucket_counter(pb):
    return of13.bucket_counter(
        packet_count=pb.packet_count,
        byte_count=pb.byte_count)


def ofp_bucket_to_loxi_bucket(pb):
    return of13.bucket(
        weight=pb.weight,
        watch_port=pb.watch_port,
        watch_group=pb.watch_group,
        actions=[to_loxi(action) for action in pb.actions]
    )


to_loxi_converters = {
    'ofp_port': ofp_port_to_loxi_port_desc,
    'ofp_port_status': ofp_port_status_to_loxi_port_status,
    'ofp_flow_stats': ofp_flow_stats_to_loxi_flow_stats,
    'ofp_packet_in': ofp_packet_in_to_loxi_packet_in,
    'ofp_group_stats': ofp_group_stats_to_loxi_group_stats,
    'ofp_group_desc': ofp_group_desc_to_loxi_group_desc,
    'ofp_bucket_counter': ofp_bucket_counter_to_loxy_bucket_counter,
    'ofp_bucket': ofp_bucket_to_loxi_bucket,
    'ofp_action': make_loxi_action,
    'ofp_port_stats': ofp_port_stats_to_loxi_port_stats
}


def loxi_flow_mod_to_ofp_flow_mod(lo):
    return pb2.ofp_flow_mod(
        cookie=lo.cookie,
        cookie_mask=lo.cookie_mask,
        table_id=lo.table_id,
        command=lo._command,
        idle_timeout=lo.idle_timeout,
        hard_timeout=lo.hard_timeout,
        priority=lo.priority,
        buffer_id=lo.buffer_id,
        out_port=lo.out_port,
        out_group=lo.out_group,
        flags=lo.flags,
        match=to_grpc(lo.match),
        instructions=[to_grpc(i) for i in lo.instructions])


def loxi_group_mod_to_ofp_group_mod(lo):
    return pb2.ofp_group_mod(
        command=lo.command,
        type=lo.group_type,
        group_id=lo.group_id,
        buckets=[to_grpc(b) for b in lo.buckets])


def loxi_packet_out_to_ofp_packet_out(lo):
    return pb2.ofp_packet_out(
        buffer_id=lo.buffer_id,
        in_port=lo.in_port,
        actions=[to_grpc(a) for a in lo.actions],
        data=lo.data)


def loxi_match_v3_to_ofp_match(lo):
    return pb2.ofp_match(
        type=pb2.OFPMT_OXM,
        oxm_fields=[to_grpc(f) for f in lo.oxm_list])


def loxi_bucket_to_ofp_bucket(lo):
    return pb2.ofp_bucket(
        weight=lo.weight,
        watch_port=lo.watch_port,
        watch_group=lo.watch_group,
        actions=[to_grpc(a) for a in lo.actions])


def loxi_oxm_eth_type_to_ofp_oxm(lo):
    return pb2.ofp_oxm_field(
        oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
        ofb_field=pb2.ofp_oxm_ofb_field(
            type=pb2.OFPXMT_OFB_ETH_TYPE,
            eth_type=lo.value))


def loxi_oxm_in_port_to_ofp_oxm(lo):
    return pb2.ofp_oxm_field(
        oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
        ofb_field=pb2.ofp_oxm_ofb_field(
            type=pb2.OFPXMT_OFB_IN_PORT,
            port=lo.value))


def loxi_oxm_ip_proto_to_ofp_oxm(lo):
    return pb2.ofp_oxm_field(
        oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
        ofb_field=pb2.ofp_oxm_ofb_field(
            type=pb2.OFPXMT_OFB_IP_PROTO,
            ip_proto=lo.value))


def loxi_oxm_vlan_vid_to_ofp_oxm(lo):
    return pb2.ofp_oxm_field(
        oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
        ofb_field=pb2.ofp_oxm_ofb_field(
            type=pb2.OFPXMT_OFB_VLAN_VID,
            vlan_vid=lo.value))


def loxi_oxm_vlan_pcp_to_ofp_oxm(lo):
    return pb2.ofp_oxm_field(
        oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
        ofb_field=pb2.ofp_oxm_ofb_field(
            type=pb2.OFPXMT_OFB_VLAN_PCP,
            vlan_pcp=lo.value))


def loxi_oxm_ipv4_dst_to_ofp_oxm(lo):
    return pb2.ofp_oxm_field(
        oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
        ofb_field=pb2.ofp_oxm_ofb_field(
            type=pb2.OFPXMT_OFB_IPV4_DST,
            ipv4_dst=lo.value))


def loxi_oxm_udp_dst_to_ofp_oxm(lo):
    return pb2.ofp_oxm_field(
        oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
        ofb_field=pb2.ofp_oxm_ofb_field(
            type=pb2.OFPXMT_OFB_UDP_DST,
            udp_dst=lo.value))


def loxi_oxm_udp_src_to_ofp_oxm(lo):
    return pb2.ofp_oxm_field(
        oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
        ofb_field=pb2.ofp_oxm_ofb_field(
            type=pb2.OFPXMT_OFB_UDP_SRC,
            udp_src=lo.value))


def loxi_oxm_metadata_to_ofp_oxm(lo):
    return pb2.ofp_oxm_field(
        oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
        ofb_field=pb2.ofp_oxm_ofb_field(
            type=pb2.OFPXMT_OFB_METADATA,
            table_metadata=lo.value))


def loxi_apply_actions_to_ofp_instruction(lo):
    return pb2.ofp_instruction(
        type=pb2.OFPIT_APPLY_ACTIONS,
        actions=pb2.ofp_instruction_actions(
            actions=[to_grpc(a) for a in lo.actions]))

def loxi_clear_actions_to_ofp_instruction(lo):
    return pb2.ofp_instruction(
        type=pb2.OFPIT_CLEAR_ACTIONS)


def loxi_goto_table_to_ofp_instruction(lo):
    return pb2.ofp_instruction(
        type=pb2.OFPIT_GOTO_TABLE,
        goto_table=pb2.ofp_instruction_goto_table(table_id=lo.table_id))


def loxi_output_action_to_ofp_action(lo):
    return pb2.ofp_action(
        type=pb2.OFPAT_OUTPUT,
        output=pb2.ofp_action_output(port=lo.port, max_len=lo.max_len))


def loxi_group_action_to_ofp_action(lo):
    return pb2.ofp_action(
        type=pb2.OFPAT_GROUP,
        group=pb2.ofp_action_group(group_id=lo.group_id))


def loxi_set_field_action_to_ofp_action(lo):
    return pb2.ofp_action(
        type=pb2.OFPAT_SET_FIELD,
        set_field=pb2.ofp_action_set_field(field=to_grpc(lo.field)))


def loxi_pop_vlan_action_to_ofp_action(lo):
    return pb2.ofp_action(type=pb2.OFPAT_POP_VLAN)


def loxi_push_vlan_action_to_ofp_action(lo):
    return pb2.ofp_action(
        type=pb2.OFPAT_PUSH_VLAN,
        push=pb2.ofp_action_push(ethertype=lo.ethertype))


to_grpc_converters = {

    of13.message.flow_add: loxi_flow_mod_to_ofp_flow_mod,
    of13.message.flow_delete: loxi_flow_mod_to_ofp_flow_mod,
    of13.message.flow_delete_strict: loxi_flow_mod_to_ofp_flow_mod,
    of13.message.flow_modify: loxi_flow_mod_to_ofp_flow_mod,
    of13.message.flow_modify_strict: loxi_flow_mod_to_ofp_flow_mod,

    of13.message.group_add: loxi_group_mod_to_ofp_group_mod,
    of13.message.group_delete: loxi_group_mod_to_ofp_group_mod,
    of13.message.group_modify: loxi_group_mod_to_ofp_group_mod,
    of13.message.packet_out: loxi_packet_out_to_ofp_packet_out,

    of13.common.match_v3: loxi_match_v3_to_ofp_match,
    of13.common.bucket: loxi_bucket_to_ofp_bucket,

    of13.oxm.eth_type: loxi_oxm_eth_type_to_ofp_oxm,
    of13.oxm.in_port: loxi_oxm_in_port_to_ofp_oxm,
    of13.oxm.ip_proto: loxi_oxm_ip_proto_to_ofp_oxm,
    of13.oxm.vlan_vid: loxi_oxm_vlan_vid_to_ofp_oxm,
    of13.oxm.vlan_pcp: loxi_oxm_vlan_pcp_to_ofp_oxm,
    of13.oxm.ipv4_dst: loxi_oxm_ipv4_dst_to_ofp_oxm,
    of13.oxm.udp_src: loxi_oxm_udp_src_to_ofp_oxm,
    of13.oxm.udp_dst: loxi_oxm_udp_dst_to_ofp_oxm,
    of13.oxm.metadata: loxi_oxm_metadata_to_ofp_oxm,

    of13.instruction.apply_actions: loxi_apply_actions_to_ofp_instruction,
    of13.instruction.clear_actions: loxi_clear_actions_to_ofp_instruction,
    of13.instruction.goto_table: loxi_goto_table_to_ofp_instruction,

    of13.action.output: loxi_output_action_to_ofp_action,
    of13.action.group: loxi_group_action_to_ofp_action,
    of13.action.set_field: loxi_set_field_action_to_ofp_action,
    of13.action.pop_vlan: loxi_pop_vlan_action_to_ofp_action,
    of13.action.push_vlan: loxi_push_vlan_action_to_ofp_action,
}
