/*
 * Copyright (c) 2017 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.
 */
/**
 * bier_imposition : The BIER imposition object
 *
 * A BIER imposition object is present in the IP mcast output list
 * and represents the imposition of a BIER bitmask. After BIER header
 * imposition the packet is forward within the appropriate/specifid
 * BIER table
 */

#include <vnet/bier/bier_imp.h>
#include <vnet/bier/bier_table.h>
#include <vnet/bier/bier_hdr_inlines.h>
#include <vnet/fib/fib_node.h>
#include <vnet/mpls/mpls_types.h>

/**
 * The memory pool of all imp objects
 */
bier_imp_t *bier_imp_pool;

/**
 * When constructing the BIER imp ID from an index and BSL, shift
 * the BSL this far
 */
#define BIER_IMP_ID_HLEN_SHIFT 24

static void
bier_imp_lock_i (bier_imp_t *bi)
{
    bi->bi_locks++;
}

void
bier_imp_lock (index_t bii)
{
    bier_imp_lock_i(bier_imp_get(bii));
}

static index_t
bier_imp_get_index(bier_imp_t *bi)
{
    return (bi - bier_imp_pool);
}

index_t
bier_imp_add_or_lock (const bier_table_id_t *bti,
                      bier_bp_t sender,
                      const bier_bit_string_t *bs)
{
    bier_imp_t *bi = NULL;
    fib_protocol_t fproto;
    index_t btii;

    pool_get_aligned(bier_imp_pool, bi, CLIB_CACHE_LINE_BYTES);

    bi->bi_tbl = *bti;
    btii = bier_table_lock(bti);

    /*
     * init the BIER header we will paint on in the data plane
     */
    bier_hdr_init(&bi->bi_hdr,
                  BIER_HDR_VERSION_1,
                  BIER_HDR_PROTO_INVALID, // filled in later
                  bti->bti_hdr_len,
                  0, // entropy
                  sender);
    bier_hdr_hton(&bi->bi_hdr);
    clib_memcpy_fast(&bi->bi_bits, bs->bbs_buckets, bs->bbs_len);

    bier_imp_lock_i(bi);

    /*
     * get and stack on the forwarding info from the table
     */
    FOR_EACH_FIB_IP_PROTOCOL(fproto)
    {
        /*
         * initialise to invalid first, lest we pick up garbage
         * from the pool alloc
         */
        dpo_id_t dpo = DPO_INVALID;
        bi->bi_dpo[fproto] = dpo;

        bier_table_contribute_forwarding(btii, &dpo);
        dpo_stack(DPO_BIER_IMP, fib_proto_to_dpo(fproto),
                  &bi->bi_dpo[fproto],
                  &dpo);
        dpo_reset(&dpo);
    }

    return (bier_imp_get_index(bi));
}

void
bier_imp_unlock (index_t bii)
{
    fib_protocol_t fproto;
    bier_imp_t *bi;

    if (INDEX_INVALID == bii)
    {
        return;
    }

    bi = bier_imp_get(bii);

    bi->bi_locks--;

    if (0 == bi->bi_locks)
    {
        bier_table_unlock(&bi->bi_tbl);

        FOR_EACH_FIB_IP_PROTOCOL(fproto)
        {
            dpo_reset(&bi->bi_dpo[fproto]);
        }
        pool_put(bier_imp_pool, bi);
    }
}

u8*
format_bier_imp (u8* s, va_list *args)
{
    index_t bii = va_arg (*args, index_t);
    u32 indent = va_arg(*args, u32);
    bier_show_flags_t flags = va_arg(*args, bier_show_flags_t);
    bier_imp_t *bi;

    bi = bier_imp_get(bii);

    s = format(s, "bier-imp:[%d]: tbl:[%U] hdr:[%U]",
               bier_imp_get_index(bi),
               format_bier_table_id, &bi->bi_tbl,
               format_bier_hdr, &bi->bi_hdr);

    if (BIER_SHOW_DETAIL & flags)
    {
        bier_bit_string_t bbs;
        bier_hdr_t copy;

        copy = bi->bi_hdr;
        bier_hdr_ntoh(&copy);
        bier_bit_string_init(&bbs,
                             bier_hdr_get_len_id(&copy),
                             bi->bi_bits);

        s = format(s, "\n%U%U",
                   format_white_space, indent,
                   format_bier_bit_string, &bbs);
        s = format(s, "\n%U%U",
                   format_white_space, indent,
                   format_dpo_id, &bi->bi_dpo, indent+2);
    }

    return (s);
}

void
bier_imp_contribute_forwarding (index_t bii,
                                dpo_proto_t proto,
                                dpo_id_t *dpo)
{
    dpo_set(dpo, DPO_BIER_IMP, proto, bii);
}

const static char* const bier_imp_ip4_nodes[] =
{
    "bier-imp-ip4",
    NULL,
};
const static char* const bier_imp_ip6_nodes[] =
{
    "bier-imp-ip6",
    NULL,
};

const static char* const * const bier_imp_nodes[DPO_PROTO_NUM] =
{
    [DPO_PROTO_IP4]  = bier_imp_ip4_nodes,
    [DPO_PROTO_IP6]  = bier_imp_ip6_nodes,
};

static void
bier_imp_dpo_lock (dpo_id_t *dpo)
{
    bier_imp_lock(dpo->dpoi_index);
}

static void
bier_imp_dpo_unlock (dpo_id_t *dpo)
{
    bier_imp_unlock(dpo->dpoi_index);
}

static void
bier_imp_dpo_mem_show (void)
{
    fib_show_memory_usage("BIER imposition",
                          pool_elts(bier_imp_pool),
                          pool_len(bier_imp_pool),
                          sizeof(bier_imp_t));
}

static u8*
format_bier_imp_dpo (u8* s, va_list *ap)
{
    index_t index = va_arg(*ap, index_t);
    u32 indent = va_arg(*ap, u32);

    s = format(s, "%U", format_bier_imp, index, indent, BIER_SHOW_DETAIL);

    return (s);
}

const static dpo_vft_t bier_imp_vft = {
    .dv_lock = bier_imp_dpo_lock,
    .dv_unlock = bier_imp_dpo_unlock,
    .dv_format = format_bier_imp_dpo,
    .dv_mem_show = bier_imp_dpo_mem_show,
};

clib_error_t *
bier_imp_db_module_init (vlib_main_t *vm)
{
    dpo_register(DPO_BIER_IMP, &bier_imp_vft, bier_imp_nodes);

    return (NULL);
}

VLIB_INIT_FUNCTION (bier_imp_db_module_init);

static clib_error_t *
show_bier_imp (vlib_main_t * vm,
               unformat_input_t * input,
               vlib_cli_command_t * cmd)
{
    bier_imp_t *bi;
    index_t bii;

    bii = INDEX_INVALID;

    while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
        if (unformat (input, "%d", &bii))
            ;
        else
        {
            break;
        }
    }

    if (INDEX_INVALID == bii)
    {
        pool_foreach(bi, bier_imp_pool,
        ({
            vlib_cli_output(vm, "%U", format_bier_imp,
                            bier_imp_get_index(bi),
                            1,
                            BIER_SHOW_BRIEF);
        }));
    }
    else
    {
        if (pool_is_free_index(bier_imp_pool, bii))
        {
            vlib_cli_output(vm, "No such BIER imposition: %d", bii);
        }
        else
        {
            vlib_cli_output(vm, "%U", format_bier_imp, bii, 1,
                            BIER_SHOW_DETAIL);
        }
    }
    return (NULL);
}

VLIB_CLI_COMMAND (show_bier_imp_node, static) = {
    .path = "show bier imp",
    .short_help = "show bier imp [index]",
    .function = show_bier_imp,
};
