/*
 * Copyright (c) 2016 Cisco and/or its affiliates.
 * 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.
 */

#include <vnet/vnet.h>
#include <vlibmemory/api.h>
#include <vnet/fib/fib_api.h>
#include <vnet/fib/fib_table.h>
#include <vnet/mfib/mfib_table.h>
#include <vnet/bier/bier_disp_table.h>
#include <vnet/dpo/ip_null_dpo.h>

#include <vnet/vnet_msg_enum.h>

#define vl_typedefs		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_typedefs

#define vl_endianfun		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_endianfun

/* instantiate all the print functions we know about */
#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
#define vl_printfun
#include <vnet/vnet_all_api_h.h>
#undef vl_printfun

#include <vlibapi/api_helper_macros.h>

int
fib_path_api_parse (const vl_api_fib_path_t *in,
                    fib_route_path_t *out)
{
    fib_route_path_flags_t path_flags;
    mpls_label_t next_hop_via_label;
    int rv = 0, n_labels;
    u8 ii;

    path_flags = FIB_ROUTE_PATH_FLAG_NONE;
    next_hop_via_label = ntohl (in->via_label);
    clib_memset(out, 0, sizeof(*out));
    out->frp_sw_if_index = ~0;

    out->frp_proto = in->afi;
    // .frp_addr = (NULL == next_hop ? zero_addr : *next_hop),
    out->frp_sw_if_index = ntohl(in->sw_if_index);
    out->frp_weight = in->weight;
    out->frp_preference = in->preference;

    if (DPO_PROTO_IP4 == out->frp_proto ||
        DPO_PROTO_IP6 == out->frp_proto ||
        DPO_PROTO_MPLS == out->frp_proto)
    {
        out->frp_fib_index = fib_table_find (dpo_proto_to_fib(out->frp_proto),
                                             ntohl (in->table_id));

        if (~0 == out->frp_fib_index)
            return (VNET_API_ERROR_NO_SUCH_FIB);
    }

    /*
     * the special INVALID label meams we are not recursing via a
     * label. Exp-null value is never a valid via-label so that
     * also means it's not a via-label and means clients that set
     * it to 0 by default get the expected behaviour
     */
    if ((MPLS_LABEL_INVALID != next_hop_via_label) &&
        (0 != next_hop_via_label))
    {
        out->frp_proto = DPO_PROTO_MPLS;
        out->frp_local_label = next_hop_via_label;
        out->frp_eos = MPLS_NON_EOS;
    }

    n_labels = in->n_labels;
    if (n_labels == 0)
        ;
    else
    {
        vec_validate (out->frp_label_stack, n_labels - 1);
        for (ii = 0; ii < n_labels; ii++)
        {
            out->frp_label_stack[ii].fml_value =
                ntohl(in->label_stack[ii].label);
            out->frp_label_stack[ii].fml_ttl =
                in->label_stack[ii].ttl;
            out->frp_label_stack[ii].fml_exp =
                in->label_stack[ii].exp;
            out->frp_label_stack[ii].fml_mode =
                (in->label_stack[ii].is_uniform ?
                 FIB_MPLS_LSP_MODE_UNIFORM :
                 FIB_MPLS_LSP_MODE_PIPE);
        }
    }

    if (in->is_dvr)
        path_flags |= FIB_ROUTE_PATH_DVR;
    if (in->is_resolve_host)
        path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
    if (in->is_resolve_attached)
        path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED;
    /* if (in->is_interface_rx) */
    /*     path_flags |= FIB_ROUTE_PATH_INTF_RX; */
    /* if (in->is_rpf_id) */
    /*     path_flags |= FIB_ROUTE_PATH_RPF_ID; */
    if (in->is_source_lookup)
        path_flags |= FIB_ROUTE_PATH_SOURCE_LOOKUP;

    if (in->is_udp_encap)
    {
        path_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
        out->frp_udp_encap_id = ntohl(in->next_hop_id);
    }
    else
    {
        if (DPO_PROTO_IP4 == in->afi)
        {
            clib_memcpy (&out->frp_addr.ip4,
                         in->next_hop,
                         sizeof (out->frp_addr.ip4));
        }
        else if (DPO_PROTO_IP6 == in->afi)
        {
            clib_memcpy (&out->frp_addr.ip6,
                         in->next_hop,
                         sizeof (out->frp_addr.ip6));
        }

        if (ip46_address_is_zero(&out->frp_addr))
        {
            if (DPO_PROTO_BIER == in->afi)
            {
                index_t bdti;

                bdti = bier_disp_table_find(ntohl(in->table_id));

                if (INDEX_INVALID != bdti)
                {
                    out->frp_fib_index = bdti;
                    out->frp_proto = DPO_PROTO_BIER;
                }
                else
                {
                    rv = VNET_API_ERROR_NO_SUCH_FIB;
                }
            }
            else if (out->frp_sw_if_index == ~0 &&
                     out->frp_fib_index != ~0)
            {
                path_flags |= FIB_ROUTE_PATH_DEAG;
            }
        }
    }

    out->frp_flags = path_flags;

    return (rv);
}

void
fib_prefix_to_api (const fib_prefix_t *pfx,
                   u8 address[16],
                   u8 *length,
                   u8 *is_ip6)
{
    *length = pfx->fp_len;
    *is_ip6 = (FIB_PROTOCOL_IP6 == pfx->fp_proto ? 1 : 0);

    if (FIB_PROTOCOL_IP6 == pfx->fp_proto)
    {
        memcpy (address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
    }
    else
    {
        memcpy (address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
    }
}

static void
fib_api_path_copy_next_hop (const fib_route_path_encode_t * api_rpath, void *fp_arg)
{
  int is_ip4;
  vl_api_fib_path_t *fp = (vl_api_fib_path_t *) fp_arg;

  if (api_rpath->rpath.frp_proto == DPO_PROTO_IP4)
    fp->afi = IP46_TYPE_IP4;
  else if (api_rpath->rpath.frp_proto == DPO_PROTO_IP6)
    fp->afi = IP46_TYPE_IP6;
  else
    {
      is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
      if (is_ip4)
	fp->afi = IP46_TYPE_IP4;
      else
	fp->afi = IP46_TYPE_IP6;
    }
  if (fp->afi == IP46_TYPE_IP4)
    memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip4,
	    sizeof (api_rpath->rpath.frp_addr.ip4));
  else
    memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip6,
	    sizeof (api_rpath->rpath.frp_addr.ip6));
}

void
fib_api_path_encode (const fib_route_path_encode_t * api_rpath,
                     vl_api_fib_path_t *out)
{
    int ii;

    clib_memset (out, 0, sizeof (*out));
    switch (api_rpath->dpo.dpoi_type)
    {
    case DPO_RECEIVE:
        out->is_local = true;
        break;
    case DPO_DROP:
        out->is_drop = true;
        break;
    case DPO_IP_NULL:
        switch (ip_null_dpo_get_action(api_rpath->dpo.dpoi_index))
        {
        case IP_NULL_ACTION_NONE:
            out->is_drop = true;
            break;
        case IP_NULL_ACTION_SEND_ICMP_UNREACH:
            out->is_unreach = true;
            break;
        case IP_NULL_ACTION_SEND_ICMP_PROHIBIT:
            out->is_prohibit = true;
            break;
        default:
            break;
        }
        break;
    default:
        break;
    }
    out->weight = api_rpath->rpath.frp_weight;
    out->preference = api_rpath->rpath.frp_preference;
    out->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
    out->afi = api_rpath->rpath.frp_proto;
    fib_api_path_copy_next_hop (api_rpath, out);

    if (0 != api_rpath->rpath.frp_fib_index)
    {
        if ((DPO_PROTO_IP6 == api_rpath->rpath.frp_proto) ||
            (DPO_PROTO_IP4 == api_rpath->rpath.frp_proto))
        {
            if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_RPF_ID)
            {
                out->table_id =
                    htonl(mfib_table_get_table_id(
                              api_rpath->rpath.frp_fib_index,
                              dpo_proto_to_fib(api_rpath->rpath.frp_proto)));
            }
            else
            {
                out->table_id =
                    htonl(fib_table_get_table_id(
                              api_rpath->rpath.frp_fib_index,
                              dpo_proto_to_fib(api_rpath->rpath.frp_proto)));
            }
        }
    }

    if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_DVR)
    {
        out->is_dvr = 1;
    }
    if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_UDP_ENCAP)
    {
        out->is_udp_encap = 1;
        out->next_hop_id = api_rpath->rpath.frp_udp_encap_id;
    }
    if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_INTF_RX)
    {
        out->is_interface_rx = 1;
    }
    if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_LOCAL)
    {
        out->is_local = 1;
    }
    if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_RESOLVE_VIA_HOST)
    {
        out->is_resolve_host = 1;
    }
    if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED)
    {
        out->is_resolve_attached = 1;
    }
    /* if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_ATTACHED) { */
    /*     out->is_attached = 1; */
    /* } */
    /* if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_CONNECTED) { */
    /*     out->is_connected = 1; */
    /* } */
    if (api_rpath->rpath.frp_label_stack)
    {
        for (ii = 0; ii < vec_len(api_rpath->rpath.frp_label_stack); ii++)
        {
            out->label_stack[ii].label =
                htonl(api_rpath->rpath.frp_label_stack[ii].fml_value);
            out->label_stack[ii].ttl =
                api_rpath->rpath.frp_label_stack[ii].fml_ttl;
            out->label_stack[ii].exp =
                api_rpath->rpath.frp_label_stack[ii].fml_exp;
        }
        out->n_labels = ii;
    }
}

fib_protocol_t
fib_proto_from_api_address_family (int af)
{
    switch (clib_net_to_host_u32 (af))
    {
    case ADDRESS_IP4:
        return (FIB_PROTOCOL_IP4);
    case ADDRESS_IP6:
        return (FIB_PROTOCOL_IP6);
    }

    ASSERT(0);
    return (FIB_PROTOCOL_IP4);
}

int
fib_proto_to_api_address_family (fib_protocol_t fproto)
{
    switch (fproto)
    {
    case FIB_PROTOCOL_IP4:
        return (clib_net_to_host_u32 (ADDRESS_IP4));
    case FIB_PROTOCOL_IP6:
        return (clib_net_to_host_u32 (ADDRESS_IP6));
    default:
        break;
    }

    ASSERT(0);
    return (clib_net_to_host_u32 (ADDRESS_IP4));
}
