/*
 * 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 <assert.h>
#include "os/mynewt.h"
#include "modlog/modlog.h"
#include "bootutil/image.h"
#include "bootutil/bootutil.h"
#include "img_mgmt/img_mgmt.h"
#include "config/config.h"
#include "config/config_file.h"
#include "reboot/log_reboot.h"
#include "bsp/bsp.h"
#include "flash_map/flash_map.h"
#include "tinycbor/cbor.h"
#include "tinycbor/cbor_buf_writer.h"

uint16_t reboot_cnt;
static int8_t log_reboot_written;

static char *reboot_conf_get(int argc, char **argv, char *buf, int max_len);
static int reboot_conf_set(int argc, char **argv, char *val);
static int reboot_conf_export(void (*export_func)(char *name, char *val),
                              enum conf_export_tgt tgt);

struct conf_handler reboot_conf_handler = {
    .ch_name = "reboot",
    .ch_get = reboot_conf_get,
    .ch_set = reboot_conf_set,
    .ch_commit = NULL,
    .ch_export = reboot_conf_export
};

#if MYNEWT_VAL(REBOOT_LOG_FCB)
static struct fcb_log reboot_log_fcb;
static struct log reboot_log;
#if MYNEWT_VAL(LOG_FCB)
static struct flash_area reboot_sector;
#endif
#if MYNEWT_VAL(LOG_FCB2)
static struct flash_sector_range reboot_sector;
#endif
#endif


#if MYNEWT_VAL(REBOOT_LOG_CONSOLE)
static int
log_reboot_init_console(void)
{
    int rc;

    rc = modlog_register(LOG_MODULE_REBOOT, log_console_get(), LOG_SYSLEVEL,
                         NULL);
    if (rc != 0) {
        return rc;
    }

    return 0;

}
#endif

#if MYNEWT_VAL(REBOOT_LOG_FCB)
static int
log_reboot_init_fcb(void)
{
    const struct flash_area *ptr;
#if MYNEWT_VAL(LOG_FCB)
    struct fcb *fcbp;
#elif MYNEWT_VAL(LOG_FCB2)
    struct fcb2 *fcbp;
#endif
    int rc;

    if (flash_area_open(MYNEWT_VAL(REBOOT_LOG_FLASH_AREA), &ptr)) {
        return SYS_EUNKNOWN;
    }

    reboot_log_fcb.fl_entries = MYNEWT_VAL(REBOOT_LOG_ENTRY_COUNT);
    fcbp = &reboot_log_fcb.fl_fcb;
#if MYNEWT_VAL(LOG_FCB)
    reboot_sector = *ptr;
    fcbp->f_magic = 0x7EADBADF;
    fcbp->f_version = g_log_info.li_version;
    fcbp->f_sector_cnt = 1;
    fcbp->f_sectors = &reboot_sector;

    rc = fcb_init(fcbp);
    if (rc) {
        flash_area_erase(ptr, 0, ptr->fa_size);
        rc = fcb_init(fcbp);
        if (rc) {
            return rc;
        }
    }
#endif
#if MYNEWT_VAL(LOG_FCB2)
    fcbp->f_magic = 0x8EADBAE0;
    fcbp->f_version = g_log_info.li_version;
    fcbp->f_sector_cnt = 1;
    fcbp->f_range_cnt = 1;
    fcbp->f_ranges = &reboot_sector;
    reboot_sector.fsr_flash_area = *ptr;
    reboot_sector.fsr_sector_count = 1;
    reboot_sector.fsr_sector_size = ptr->fa_size;
    reboot_sector.fsr_align = flash_area_align(ptr);

    rc = fcb2_init(fcbp);
    if (rc) {
        flash_area_erase(ptr, 0, ptr->fa_size);
        rc = fcb2_init(fcbp);
        if (rc) {
            return rc;
        }
    }
#endif

    rc = log_register("reboot_log", &reboot_log, &log_fcb_handler,
                      &reboot_log_fcb, LOG_SYSLEVEL);
    if (rc != 0) {
        return rc;
    }

    rc = modlog_register(LOG_MODULE_REBOOT, &reboot_log, LOG_SYSLEVEL,
                         NULL);
    if (rc != 0) {
        return rc;
    }

    return 0;
}
#endif

static int
reboot_cnt_inc(void)
{
    char str[12];
    int rc;

    reboot_cnt++;
    rc = conf_save_one("reboot/reboot_cnt",
                       conf_str_from_value(CONF_INT16, &reboot_cnt,
                                           str, sizeof(str)));
    return rc;
}

/**
 * Logs reboot with the specified reason
 * @param reason for reboot
 * @return 0 on success; non-zero on failure
 */
static int
log_reboot_write(const struct log_reboot_info *info)
{
    struct image_version ver;
    uint8_t hash[32];
    char buf[MYNEWT_VAL(REBOOT_LOG_BUF_SIZE)];
    uint8_t cbor_enc_buf[MYNEWT_VAL(REBOOT_LOG_BUF_SIZE)];
    int off;
    int rc;
    int i;
    struct cbor_buf_writer writer;
    struct CborEncoder enc;
    struct CborEncoder map;
    size_t cbor_buf_len;
    uint32_t flags;
    uint8_t state_flags;

#if MYNEWT_VAL(REBOOT_LOG_FCB)
    {
        const struct flash_area *ptr;
        if (flash_area_open(MYNEWT_VAL(REBOOT_LOG_FLASH_AREA), &ptr)) {
            return 0;
        }
    }
#endif

    rc = img_mgmt_read_info(boot_current_slot, &ver, hash, &flags);
    if (rc != 0) {
        return rc;
    }

    memset(cbor_enc_buf, 0, sizeof cbor_enc_buf);

    cbor_buf_writer_init(&writer, cbor_enc_buf, sizeof cbor_enc_buf);
    cbor_encoder_init(&enc, &writer.enc, 0);
    rc = cbor_encoder_create_map(&enc, &map, CborIndefiniteLength);
    if (rc != 0) {
        return rc;
    }

    cbor_encode_text_stringz(&map, "rsn");
    cbor_encode_text_stringz(&map,log_reboot_reason_str(info->reason));

    cbor_encode_text_stringz(&map, "cnt");
    cbor_encode_int(&map, reboot_cnt);

    cbor_encode_text_stringz(&map, "img");
    snprintf(buf, sizeof buf, "%u.%u.%u.%u",
                  ver.iv_major, ver.iv_minor, ver.iv_revision,
                  (unsigned int)ver.iv_build_num);
    cbor_encode_text_stringz(&map, buf);

    cbor_encode_text_stringz(&map, "hash");
    off = 0;
    for (i = 0; i < sizeof hash; i++) {
        off += snprintf(buf + off, sizeof buf - off, "%02x",
                        (unsigned int)hash[i]);
    }
    cbor_encode_text_stringz(&map, buf);

    if (info->file != NULL) {
        cbor_encode_text_stringz(&map, "die");
        off  = 0;

        /* If die filename is longer than 1/3 of total allocated
         * buffer, then trim the filename from left. */
        if (strlen(info->file) > ((sizeof buf) / 3)) {
            off = strlen(info->file) - ((sizeof buf) / 3);
        }
        snprintf(buf, sizeof buf, "%s:%d",
                &info->file[off], info->line);
        cbor_encode_text_stringz(&map, buf);
    }

    if (info->pc != 0) {
        cbor_encode_text_stringz(&map, "pc");
        cbor_encode_int(&map, info->pc);
    }

    state_flags = img_mgmt_state_flags(boot_current_slot);
    cbor_encode_text_stringz(&map, "flags");
    off = 0;
    buf[0] = '\0';

    if (state_flags & IMG_MGMT_STATE_F_ACTIVE) {
        off += snprintf(buf + off, sizeof buf - off, "%s ", "active");
    }
    if (!(flags & IMAGE_F_NON_BOOTABLE)) {
        off += snprintf(buf + off, sizeof buf - off, "%s ", "bootable");
    }
    if (state_flags & IMG_MGMT_STATE_F_CONFIRMED) {
        off += snprintf(buf + off, sizeof buf - off, "%s ", "confirmed");
    }
    if (state_flags & IMG_MGMT_STATE_F_PENDING) {
        off += snprintf(buf + off, sizeof buf - off, "%s ", "pending");
    }
    if (off > 1) {
        buf[off - 1] = '\0';
    }
    cbor_encode_text_stringz(&map, buf);

    /* Find length of the CBOR encoded log entry. */
    cbor_buf_len = cbor_buf_writer_buffer_size(&writer, cbor_enc_buf) + 1;

    rc = cbor_encoder_close_container(&enc, &map);
    if (rc != 0) {
        return SYS_ENOMEM;
    }

    /* Log a CBOR encoded reboot record. */
    modlog_append(LOG_MODULE_REBOOT, LOG_LEVEL_CRITICAL, LOG_ETYPE_CBOR,
                  cbor_enc_buf, cbor_buf_len);

    return 0;
}

int
log_reboot(const struct log_reboot_info *info)
{
    int rc;

    /* Don't log a second reboot entry. */
    if (log_reboot_written) {
        return 0;
    }

    rc = log_reboot_write(info);
    if (rc != 0) {
        return rc;
    }

    if (info->reason != HAL_RESET_REQUESTED &&
        info->reason != HAL_RESET_DFU) {
        /* Record that we have written a reboot entry for the current boot.
         * Upon rebooting, we won't write a second entry.
         */
        log_reboot_written = 1;
        conf_save_one("reboot/written", "1");
    }

    return 0;
}

/**
 * Increments the reboot counter and writes an entry to the reboot log, if
 * necessary.  This function should be called from main() after config
 * settings have been loaded via conf_load().
 *
 * @param reason                The cause of the reboot.
 */
void
reboot_start(enum hal_reset_reason reason)
{
    struct log_reboot_info info;

    /* If an entry wasn't written before the previous reboot, write one now. */
    if (!log_reboot_written) {
        reboot_cnt_inc();

        info = (struct log_reboot_info) {
            .reason = reason,
            .file = NULL,
            .line = 0,
            .pc = 0,
        };
        log_reboot_write(&info);
    }

    /* Record that we haven't written a reboot entry for the current boot. */
    log_reboot_written = 0;
    conf_save_one("reboot/written", "0");
}

static char *
reboot_conf_get(int argc, char **argv, char *buf, int max_len)
{
    if (argc == 1) {
        if (!strcmp(argv[0], "reboot_cnt")) {
            return conf_str_from_value(CONF_INT16, &reboot_cnt, buf, max_len);
        } else if (!strcmp(argv[0], "written")) {
            return conf_str_from_value(CONF_BOOL, &log_reboot_written,
                                       buf, max_len);
        }
    }
    return NULL;
}

static int
reboot_conf_set(int argc, char **argv, char *val)
{
    if (argc == 1) {
        if (!strcmp(argv[0], "reboot_cnt")) {
            return CONF_VALUE_SET(val, CONF_INT16, reboot_cnt);
        } else if (!strcmp(argv[0], "written")) {
            return CONF_VALUE_SET(val, CONF_INT16, log_reboot_written);
        }
    }

    return OS_ENOENT;
}

static int
reboot_conf_export(void (*func)(char *name, char *val),
                   enum conf_export_tgt tgt)
{
    char str[12];

    if (tgt == CONF_EXPORT_SHOW) {
        func("reboot/reboot_cnt",
             conf_str_from_value(CONF_INT16, &reboot_cnt, str, sizeof str));
        func("reboot/written",
             conf_str_from_value(CONF_BOOL, &log_reboot_written, str,
                                 sizeof str));
    }
    return 0;
}

const char *
log_reboot_reason_str(enum hal_reset_reason reason)
{
    static char str_reason[MYNEWT_VAL(REBOOT_LOG_REBOOT_REASON_SIZE)];

    if (reason >= HAL_RESET_OTHER) {
        snprintf(str_reason,MYNEWT_VAL(REBOOT_LOG_REBOOT_REASON_SIZE),"OTHER: 0x%X",reason - HAL_RESET_OTHER);
        return str_reason;
    }

    switch (reason) {
    case HAL_RESET_POR:
        return "HARD";
        break;
    case HAL_RESET_PIN:
        return "RESET_PIN";
        break;
    case HAL_RESET_WATCHDOG:
        return "WDOG";
        break;
    case HAL_RESET_SOFT:
        return "SOFT";
        break;
    case HAL_RESET_BROWNOUT:
        return "BROWNOUT";
        break;
    case HAL_RESET_REQUESTED:
        return "REQUESTED";
        break;
    case HAL_RESET_SYS_OFF_INT:
        return "SYSTEM_OFF_INT";
        break;
    case HAL_RESET_DFU:
        return "DFU";
        break;
    default:
        snprintf(str_reason,MYNEWT_VAL(REBOOT_LOG_REBOOT_REASON_SIZE),"UNKNOWN %d",reason);
        return str_reason;
        break;
    }
}

void
log_reboot_pkg_init(void)
{
    int rc;

    /* Ensure this function only gets called by sysinit. */
    SYSINIT_ASSERT_ACTIVE();

    rc = conf_register(&reboot_conf_handler);
    SYSINIT_PANIC_ASSERT(rc == 0);

#if MYNEWT_VAL(REBOOT_LOG_FCB)
    rc = log_reboot_init_fcb();
    SYSINIT_PANIC_ASSERT(rc == 0);
#endif
#if MYNEWT_VAL(REBOOT_LOG_CONSOLE)
    rc = log_reboot_init_console();
    SYSINIT_PANIC_ASSERT(rc == 0);
#endif
}
