/*
 * 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 <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "os/os.h"
#include "shell/shell.h"
#include "console/console.h"
#include "metrics/metrics.h"
#include "tinycbor/cbor.h"
#include "tinycbor/cbor_mbuf_reader.h"

static STAILQ_HEAD(, metrics_event_hdr) g_event_list =
                                        STAILQ_HEAD_INITIALIZER(g_event_list);

static struct metrics_event_hdr *
find_event_by_name(const char *name)
{
    struct metrics_event_hdr *hdr;

    STAILQ_FOREACH(hdr, &g_event_list, next) {
        if (!strcmp(hdr->name, name)) {
            break;
        }
    }

    return hdr;
}

static int
find_metric_by_name(struct metrics_event_hdr *hdr, const char *name)
{
    int i;

    for (i = 0; i < hdr->count; i++) {
        if (!strcmp(hdr->defs[i].name, name)) {
            return i;
        }
    }

    return -1;
}

static const char *
metric_type_str(uint8_t type)
{
    switch (type) {
    case METRICS_TYPE_SINGLE_U:
        return "unsigned";
    case METRICS_TYPE_SINGLE_S:
        return "signed";
    case METRICS_TYPE_SERIES_U8:
        return "unsigned8-series";
    case METRICS_TYPE_SERIES_S8:
        return "signed8-series";
    case METRICS_TYPE_SERIES_U16:
        return "unsigned16-series";
    case METRICS_TYPE_SERIES_S16:
        return "signed16-series";
    case METRICS_TYPE_SERIES_U32:
        return "unsigned32-series";
    case METRICS_TYPE_SERIES_S32:
        return "signed32-series";
    }

    return "<unknown>";
}

static void
print_event_metrics(struct metrics_event_hdr *hdr)
{
    int i;

    for (i = 0; i < hdr->count; i++) {
        console_printf("  %d = %s (%s, %d)\n", i, hdr->defs[i].name,
                                        metric_type_str(hdr->defs[i].type),
                                        !!(hdr->enabled & (1 << i)));
    }
}

static int
cmd_list_events(int argc, char **argv)
{
    struct metrics_event_hdr *hdr;
    bool full = false;

    if (argc > 1) {
        full = atoi(argv[1]);
    }

    STAILQ_FOREACH(hdr, &g_event_list, next) {
        console_printf("%s\n", hdr->name);
        if (full) {
            print_event_metrics(hdr);
        }
    }

    return 0;
}

static int
cmd_list_event_metrics(int argc, char **argv)
{
    struct metrics_event_hdr *hdr;

    if (argc < 2) {
        console_printf("Event name not specified\n");
        return -1;
    }

    STAILQ_FOREACH(hdr, &g_event_list, next) {
        if (!strcmp(hdr->name, argv[1])) {
            print_event_metrics(hdr);
            return 0;
        }
    }

    console_printf("Event '%s' not found\n", argv[1]);

    return -1;
}

static int
cmd_metric_set(int argc, char **argv)
{
    struct metrics_event_hdr *hdr;
    int i;

    if (argc < 4) {
        console_printf("Event and/or metric name not specified\n");
        return -1;
    }

    hdr = find_event_by_name(argv[1]);
    if (!hdr) {
        console_printf("Event '%s' not found\n", argv[1]);
        return -1;
    }

    i = find_metric_by_name(hdr, argv[2]);
    if (i < 0) {
        console_printf("Metric '%s' not found\n", argv[2]);
        return -1;
    }

    metrics_set_state(hdr, i, atoi(argv[3]));

    return -1;
}

static int
cmd_event_dump(int argc, char **argv)
{
    struct cbor_mbuf_reader reader;
    struct CborParser parser;
    struct CborValue value;
    struct metrics_event_hdr *hdr;
    struct os_mbuf *om;

    if (argc < 2) {
        console_printf("Event name not specified\n");
        return -1;
    }

    hdr = find_event_by_name(argv[1]);
    if (!hdr) {
        console_printf("Event '%s' not found\n", argv[1]);
        return -1;
    }

    /* We use msys so serializing event to CBOR will be non-destructive */
    om = os_msys_get_pkthdr(50, 0);
    metrics_event_to_cbor(hdr, om);
    cbor_mbuf_reader_init(&reader, om, 0);
    cbor_parser_init(&reader.r, 0, &parser, &value);
    cbor_value_to_pretty(stdout, &value);
    os_mbuf_free_chain(om);

    console_printf("\n");

    return 0;
}

static int
cmd_event_end(int argc, char **argv)
{
    struct metrics_event_hdr *hdr;

    if (argc < 2) {
        console_printf("Event name not specified\n");
        return -1;
    }

    hdr = find_event_by_name(argv[1]);
    if (!hdr) {
        console_printf("Event '%s' not found\n", argv[1]);
        return -1;
    }

    metrics_event_end(hdr);

    return 0;
}

static const struct shell_cmd metrics_commands[] = {
    {
        .sc_cmd = "list-events",
        .sc_cmd_func = cmd_list_events,
    },
    {
        .sc_cmd = "list-event-metrics",
        .sc_cmd_func = cmd_list_event_metrics,
    },
    {
        .sc_cmd = "metric-set",
        .sc_cmd_func = cmd_metric_set,
    },
    {
        .sc_cmd = "event-dump",
        .sc_cmd_func = cmd_event_dump,
    },
    {
        .sc_cmd = "event-end",
        .sc_cmd_func = cmd_event_end,
    },
    { },
};

int
metrics_cli_register_event(struct metrics_event_hdr *hdr)
{
    STAILQ_INSERT_TAIL(&g_event_list, hdr, next);

    return 0;
}

int
metrics_cli_init(void)
{
    shell_register("metrics", metrics_commands);

    return 0;
}
