/*
 * 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 <assert.h>
#include <string.h>

#include "tinycbor/cbor.h"
#include "cborattr/cborattr.h"
#include "mgmt/mgmt.h"
#include "os_mgmt/os_mgmt.h"
#include "os_mgmt/os_mgmt_impl.h"
#include "os_mgmt/os_mgmt_config.h"

#if OS_MGMT_ECHO
static mgmt_handler_fn os_mgmt_echo;
#endif

static mgmt_handler_fn os_mgmt_reset;

#if OS_MGMT_TASKSTAT
static mgmt_handler_fn os_mgmt_taskstat_read;
#endif

static const struct mgmt_handler os_mgmt_group_handlers[] = {
#if OS_MGMT_ECHO
    [OS_MGMT_ID_ECHO] = {
        os_mgmt_echo, os_mgmt_echo
    },
#endif
#if OS_MGMT_TASKSTAT
    [OS_MGMT_ID_TASKSTAT] = {
        os_mgmt_taskstat_read, NULL
    },
#endif
    [OS_MGMT_ID_RESET] = {
        NULL, os_mgmt_reset
    },
};

#define OS_MGMT_GROUP_SZ    \
    (sizeof os_mgmt_group_handlers / sizeof os_mgmt_group_handlers[0])

static struct mgmt_group os_mgmt_group = {
    .mg_handlers = os_mgmt_group_handlers,
    .mg_handlers_count = OS_MGMT_GROUP_SZ,
    .mg_group_id = MGMT_GROUP_ID_OS,
};

/**
 * Command handler: os echo
 */
#if OS_MGMT_ECHO
static int
os_mgmt_echo(struct mgmt_ctxt *ctxt)
{
    char echo_buf[128];
    CborError err;

    const struct cbor_attr_t attrs[2] = {
        [0] = {
            .attribute = "d",
            .type = CborAttrTextStringType,
            .addr.string = echo_buf,
            .nodefault = 1,
            .len = sizeof echo_buf,
        },
        [1] = {
            .attribute = NULL
        }
    };

    echo_buf[0] = '\0';

    err = cbor_read_object(&ctxt->it, attrs);
    if (err != 0) {
        return MGMT_ERR_EINVAL;
    }

    err |= cbor_encode_text_stringz(&ctxt->encoder, "r");
    err |= cbor_encode_text_string(&ctxt->encoder, echo_buf, strlen(echo_buf));

    if (err != 0) {
        return MGMT_ERR_ENOMEM;
    }

    return 0;
}
#endif

#if OS_MGMT_TASKSTAT
/**
 * Encodes a single taskstat entry.
 */
static int
os_mgmt_taskstat_encode_one(struct CborEncoder *encoder,
                            const struct os_mgmt_task_info *task_info)
{
    CborEncoder task_map;
    CborError err;

    err = 0;
    err |= cbor_encode_text_stringz(encoder, task_info->oti_name);
    err |= cbor_encoder_create_map(encoder, &task_map, CborIndefiniteLength);
    err |= cbor_encode_text_stringz(&task_map, "prio");
    err |= cbor_encode_uint(&task_map, task_info->oti_prio);
    err |= cbor_encode_text_stringz(&task_map, "tid");
    err |= cbor_encode_uint(&task_map, task_info->oti_taskid);
    err |= cbor_encode_text_stringz(&task_map, "state");
    err |= cbor_encode_uint(&task_map, task_info->oti_state);
    err |= cbor_encode_text_stringz(&task_map, "stkuse");
    err |= cbor_encode_uint(&task_map, task_info->oti_stkusage);
    err |= cbor_encode_text_stringz(&task_map, "stksiz");
    err |= cbor_encode_uint(&task_map, task_info->oti_stksize);
    err |= cbor_encode_text_stringz(&task_map, "cswcnt");
    err |= cbor_encode_uint(&task_map, task_info->oti_cswcnt);
    err |= cbor_encode_text_stringz(&task_map, "runtime");
    err |= cbor_encode_uint(&task_map, task_info->oti_runtime);
    err |= cbor_encode_text_stringz(&task_map, "last_checkin");
    err |= cbor_encode_uint(&task_map, task_info->oti_last_checkin);
    err |= cbor_encode_text_stringz(&task_map, "next_checkin");
    err |= cbor_encode_uint(&task_map, task_info->oti_next_checkin);
    err |= cbor_encoder_close_container(encoder, &task_map);

    if (err != 0) {
        return MGMT_ERR_ENOMEM;
    }

    return 0;
}

/**
 * Command handler: os taskstat
 */
static int
os_mgmt_taskstat_read(struct mgmt_ctxt *ctxt)
{
    struct os_mgmt_task_info task_info;
    struct CborEncoder tasks_map;
    CborError err;
    int task_idx;
    int rc;

    err = 0;
    err |= cbor_encode_text_stringz(&ctxt->encoder, "tasks");
    err |= cbor_encoder_create_map(&ctxt->encoder, &tasks_map,
                                   CborIndefiniteLength);
    if (err != 0) {
        return MGMT_ERR_ENOMEM;
    }

    /* Iterate the list of tasks, encoding each. */
    for (task_idx = 0; ; task_idx++) {
        rc = os_mgmt_impl_task_info(task_idx, &task_info);
        if (rc == MGMT_ERR_ENOENT) {
            /* No more tasks to encode. */
            break;
        } else if (rc != 0) {
            return rc;
        }

        rc = os_mgmt_taskstat_encode_one(&tasks_map, &task_info);
        if (rc != 0) {
            cbor_encoder_close_container(&ctxt->encoder, &tasks_map);
            return rc;
        }
    }

    err = cbor_encoder_close_container(&ctxt->encoder, &tasks_map);
    if (err != 0) {
        return MGMT_ERR_ENOMEM;
    }

    return 0;
}
#endif

/**
 * Command handler: os reset
 */
static int
os_mgmt_reset(struct mgmt_ctxt *ctxt)
{
    return os_mgmt_impl_reset(OS_MGMT_RESET_MS);
}

void
os_mgmt_register_group(void)
{
    mgmt_register_group(&os_mgmt_group);
}

void
os_mgmt_module_init(void)
{
    os_mgmt_register_group();
}
