/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 <string.h>

#include "tinycbor/cbor.h"
#include "mgmt/endian.h"
#include "mgmt/mgmt.h"

static mgmt_on_evt_cb *evt_cb;
static struct mgmt_group *mgmt_group_list;
static struct mgmt_group *mgmt_group_list_end;

void *
mgmt_streamer_alloc_rsp(struct mgmt_streamer *streamer, const void *req)
{
    return streamer->cfg->alloc_rsp(req, streamer->cb_arg);
}

void
mgmt_streamer_trim_front(struct mgmt_streamer *streamer, void *buf, size_t len)
{
    streamer->cfg->trim_front(buf, len, streamer->cb_arg);
}

void
mgmt_streamer_reset_buf(struct mgmt_streamer *streamer, void *buf)
{
    streamer->cfg->reset_buf(buf, streamer->cb_arg);
}

int
mgmt_streamer_write_at(struct mgmt_streamer *streamer, size_t offset,
                       const void *data, int len)
{
    return streamer->cfg->write_at(streamer->writer, offset, data, len,
                                   streamer->cb_arg);
}

int
mgmt_streamer_init_reader(struct mgmt_streamer *streamer, void *buf)
{
    return streamer->cfg->init_reader(streamer->reader, buf, streamer->cb_arg);
}

int
mgmt_streamer_init_writer(struct mgmt_streamer *streamer, void *buf)
{
    return streamer->cfg->init_writer(streamer->writer, buf, streamer->cb_arg);
}

void
mgmt_streamer_free_buf(struct mgmt_streamer *streamer, void *buf)
{
    streamer->cfg->free_buf(buf, streamer->cb_arg);
}

static struct mgmt_group *
mgmt_find_group(uint16_t group_id, uint16_t command_id)
{
    struct mgmt_group *group;

    /*
     * Find the group with the specified group id, if one exists
     * check the handler for the command id and make sure
     * that is not NULL. If that is not set, look for the group
     * with a command id that is set
     */
    for (group = mgmt_group_list; group != NULL; group = group->mg_next) {
        if (group->mg_group_id == group_id) {
            if (command_id >= group->mg_handlers_count) {
                return NULL;
            }

            if (!group->mg_handlers[command_id].mh_read &&
                !group->mg_handlers[command_id].mh_write) {
                continue;
            }

            break;
        }
    }

    return group;
}

void
mgmt_register_group(struct mgmt_group *group)
{
    if (mgmt_group_list_end == NULL) {
        mgmt_group_list = group;
    } else {
        mgmt_group_list_end->mg_next = group;
    }
    mgmt_group_list_end = group;
}

const struct mgmt_handler *
mgmt_find_handler(uint16_t group_id, uint16_t command_id)
{
    const struct mgmt_group *group;

    group = mgmt_find_group(group_id, command_id);
    if (!group) {
        return NULL;
    }

    return &group->mg_handlers[command_id];
}

int
mgmt_write_rsp_status(struct mgmt_ctxt *ctxt, int errcode)
{
    int rc;

    rc = cbor_encode_text_stringz(&ctxt->encoder, "rc");
    if (rc != 0) {
        return rc;
    }

    rc = cbor_encode_int(&ctxt->encoder, errcode);
    if (rc != 0) {
        return rc;
    }

    return 0;
}

int
mgmt_err_from_cbor(int cbor_status)
{
    switch (cbor_status) {
        case CborNoError:           return MGMT_ERR_EOK;
        case CborErrorOutOfMemory:  return MGMT_ERR_ENOMEM;
        default:                    return MGMT_ERR_EUNKNOWN;
    }
}

int
mgmt_ctxt_init(struct mgmt_ctxt *ctxt, struct mgmt_streamer *streamer)
{
    int rc;

#ifdef __ZEPHYR__
    rc = cbor_parser_cust_reader_init(streamer->reader, 0, &ctxt->parser,
                                      &ctxt->it);
#else
    rc = cbor_parser_init(streamer->reader, 0, &ctxt->parser, &ctxt->it);
#endif
    if (rc != CborNoError) {
        return mgmt_err_from_cbor(rc);
    }

#ifdef __ZEPHYR__
    cbor_encoder_cust_writer_init(&ctxt->encoder, streamer->writer, 0);
#else
    cbor_encoder_init(&ctxt->encoder, streamer->writer, 0);
#endif

    return 0;
}

void
mgmt_ntoh_hdr(struct mgmt_hdr *hdr)
{
    hdr->nh_len = ntohs(hdr->nh_len);
    hdr->nh_group = ntohs(hdr->nh_group);
}

void
mgmt_hton_hdr(struct mgmt_hdr *hdr)
{
    hdr->nh_len = htons(hdr->nh_len);
    hdr->nh_group = htons(hdr->nh_group);
}

void
mgmt_register_evt_cb(mgmt_on_evt_cb *cb)
{
    evt_cb = cb;
}

void
mgmt_evt(uint8_t opcode, uint16_t group, uint8_t id, void *arg)
{
    if (evt_cb) {
        evt_cb(opcode, group, id, arg);
    }
}
