/*
 * 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 <inttypes.h>

#include "os/mynewt.h"
#include "hal/hal_bsp.h"
#include "hal/hal_flash.h"
#include "flash_map/flash_map.h"
#include "bootutil/image.h"
#include "bootutil/bootutil.h"
#include "bootutil_priv.h"

int boot_current_slot;

const uint32_t boot_img_magic[4] = {
    0xf395c277,
    0x7fefd260,
    0x0f505235,
    0x8079b62c,
};

struct boot_swap_table {
    /** * For each field, a value of 0 means "any". */
    uint8_t bsw_magic_slot0;
    uint8_t bsw_magic_slot1;
    uint8_t bsw_image_ok_slot0;
    uint8_t bsw_image_ok_slot1;

    uint8_t bsw_swap_type;
};

/**
 * This set of tables maps image trailer contents to swap operation type.
 * When searching for a match, these tables must be iterated sequentially.
 */
static const struct boot_swap_table boot_swap_tables[] = {
    {
        /*          | slot-0     | slot-1     |
         *----------+------------+------------|
         *    magic | Unset      | Unset      |
         * image-ok | Any        | Any        |
         * ---------+------------+------------'
         * swap: none                         |
         * -----------------------------------'
         */
        .bsw_magic_slot0 =      BOOT_MAGIC_UNSET,
        .bsw_magic_slot1 =      BOOT_MAGIC_UNSET,
        .bsw_image_ok_slot0 =   0,
        .bsw_image_ok_slot1 =   0,
        .bsw_swap_type =        BOOT_SWAP_TYPE_NONE,
    },

    {
        /*          | slot-0     | slot-1     |
         *----------+------------+------------|
         *    magic | Any        | Good       |
         * image-ok | Any        | Unset      |
         * ---------+------------+------------`
         * swap: test                         |
         * -----------------------------------'
         */
        .bsw_magic_slot0 =      0,
        .bsw_magic_slot1 =      BOOT_MAGIC_GOOD,
        .bsw_image_ok_slot0 =   0,
        .bsw_image_ok_slot1 =   0xff,
        .bsw_swap_type =        BOOT_SWAP_TYPE_TEST,
    },

    {
        /*          | slot-0     | slot-1     |
         *----------+------------+------------|
         *    magic | Any        | Good       |
         * image-ok | Any        | 0x01       |
         * ---------+------------+------------`
         * swap: permanent                    |
         * -----------------------------------'
         */
        .bsw_magic_slot0 =      0,
        .bsw_magic_slot1 =      BOOT_MAGIC_GOOD,
        .bsw_image_ok_slot0 =   0,
        .bsw_image_ok_slot1 =   0x01,
        .bsw_swap_type =        BOOT_SWAP_TYPE_PERM,
    },

    {
        /*          | slot-0     | slot-1     |
         *----------+------------+------------|
         *    magic | Good       | Unset      |
         * image-ok | 0xff       | Any        |
         * ---------+------------+------------'
         * swap: revert (test image running)  |
         * -----------------------------------'
         */
        .bsw_magic_slot0 =      BOOT_MAGIC_GOOD,
        .bsw_magic_slot1 =      BOOT_MAGIC_UNSET,
        .bsw_image_ok_slot0 =   0xff,
        .bsw_image_ok_slot1 =   0,
        .bsw_swap_type =        BOOT_SWAP_TYPE_REVERT,
    },

    {
        /*          | slot-0     | slot-1     |
         *----------+------------+------------|
         *    magic | Good       | Unset      |
         * image-ok | 0x01       | Any        |
         * ---------+------------+------------'
         * swap: none (confirmed test image)  |
         * -----------------------------------'
         */
        .bsw_magic_slot0 =      BOOT_MAGIC_GOOD,
        .bsw_magic_slot1 =      BOOT_MAGIC_UNSET,
        .bsw_image_ok_slot0 =   0x01,
        .bsw_image_ok_slot1 =   0,
        .bsw_swap_type =        BOOT_SWAP_TYPE_NONE,
    },
};

#define BOOT_SWAP_TABLES_COUNT \
    (sizeof boot_swap_tables / sizeof boot_swap_tables[0])

int
boot_magic_code(const uint32_t *magic)
{
    int i;

    if (memcmp(magic, boot_img_magic, sizeof boot_img_magic) == 0) {
        return BOOT_MAGIC_GOOD;
    }

    for (i = 0; i < 4; i++) {
        if (magic[i] == 0xffffffff) {
            return BOOT_MAGIC_UNSET;
        }
    }

    return BOOT_MAGIC_BAD;
}

uint32_t
boot_status_sz(uint8_t min_write_sz)
{
    return BOOT_STATUS_MAX_ENTRIES * BOOT_STATUS_STATE_COUNT * min_write_sz;
}

uint32_t
boot_trailer_sz(uint8_t min_write_sz)
{
    return sizeof boot_img_magic            +
           boot_status_sz(min_write_sz)     +
           min_write_sz * 2;
}

static uint32_t
boot_magic_off(const struct flash_area *fap)
{
    uint32_t off_from_end;
    uint8_t elem_sz;

    elem_sz = flash_area_align(fap);

    off_from_end = boot_trailer_sz(elem_sz);

    assert(off_from_end <= fap->fa_size);
    return fap->fa_size - off_from_end;
}

uint32_t
boot_status_off(const struct flash_area *fap)
{
    return boot_magic_off(fap) + sizeof boot_img_magic;
}

static uint32_t
boot_copy_done_off(const struct flash_area *fap)
{
    return fap->fa_size - flash_area_align(fap) * 2;
}

static uint32_t
boot_image_ok_off(const struct flash_area *fap)
{
    return fap->fa_size - flash_area_align(fap);
}

int
boot_read_swap_state(const struct flash_area *fap,
                     struct boot_swap_state *state)
{
    uint32_t magic[4];
    uint32_t off;
    int rc;

    off = boot_magic_off(fap);
    rc = flash_area_read(fap, off, magic, sizeof magic);
    if (rc != 0) {
        return BOOT_EFLASH;
    }
    state->magic = boot_magic_code(magic);

    off = boot_copy_done_off(fap);
    rc = flash_area_read(fap, off, &state->copy_done, 1);
    if (rc != 0) {
        return BOOT_EFLASH;
    }

    off = boot_image_ok_off(fap);
    rc = flash_area_read(fap, off, &state->image_ok, 1);
    if (rc != 0) {
        return BOOT_EFLASH;
    }

    return 0;
}

/**
 * Reads the image trailer from the scratch area.
 */
int
boot_read_swap_state_scratch(struct boot_swap_state *state)
{
    const struct flash_area *fap;
    int rc;

    rc = flash_area_open(FLASH_AREA_IMAGE_SCRATCH, &fap);
    if (rc) {
        rc = BOOT_EFLASH;
        goto done;
    }

    rc = boot_read_swap_state(fap, state);
    if (rc != 0) {
        goto done;
    }

    rc = 0;

done:
    flash_area_close(fap);
    return rc;
}

/**
 * Reads the image trailer from a given image slot.
 */
int
boot_read_swap_state_img(int slot, struct boot_swap_state *state)
{
    const struct flash_area *fap;
    int area_id;
    int rc;

    area_id = flash_area_id_from_image_slot(slot);
    rc = flash_area_open(area_id, &fap);
    if (rc != 0) {
        rc = BOOT_EFLASH;
        goto done;
    }

    rc = boot_read_swap_state(fap, state);
    if (rc != 0) {
        goto done;
    }

    rc = 0;

done:
    flash_area_close(fap);
    return rc;
}

int
boot_write_magic(const struct flash_area *fap)
{
    uint32_t off;
    int rc;

    off = boot_magic_off(fap);

    rc = flash_area_write(fap, off, boot_img_magic, sizeof boot_img_magic);
    if (rc != 0) {
        return BOOT_EFLASH;
    }

    return 0;
}

int
boot_write_copy_done(const struct flash_area *fap)
{
    uint32_t off;
    int rc;
    uint8_t buf[8];
    uint8_t align;

    off = boot_copy_done_off(fap);

    align = hal_flash_align(fap->fa_device_id);
    memset(buf, 0xFF, 8);
    buf[0] = 1;

    rc = flash_area_write(fap, off, buf, align);
    if (rc != 0) {
        return BOOT_EFLASH;
    }

    return 0;
}

int
boot_write_image_ok(const struct flash_area *fap)
{
    uint32_t off;
    int rc;
    uint8_t buf[8];
    uint8_t align;

    off = boot_image_ok_off(fap);

    align = hal_flash_align(fap->fa_device_id);
    memset(buf, 0xFF, 8);
    buf[0] = 1;
    rc = flash_area_write(fap, off, buf, align);
    if (rc != 0) {
        return BOOT_EFLASH;
    }

    return 0;
}

int
boot_swap_type(void)
{
    const struct boot_swap_table *table;
    struct boot_swap_state state_slot0;
    struct boot_swap_state state_slot1;
    int rc;
    int i;

    rc = boot_read_swap_state_img(0, &state_slot0);
    assert(rc == 0);

    rc = boot_read_swap_state_img(1, &state_slot1);
    assert(rc == 0);

    for (i = 0; i < BOOT_SWAP_TABLES_COUNT; i++) {
        table = boot_swap_tables + i;

        if ((table->bsw_magic_slot0     == 0    ||
             table->bsw_magic_slot0     == state_slot0.magic)           &&
            (table->bsw_magic_slot1     == 0    ||
             table->bsw_magic_slot1     == state_slot1.magic)           &&
            (table->bsw_image_ok_slot0  == 0    ||
             table->bsw_image_ok_slot0  == state_slot0.image_ok)        &&
            (table->bsw_image_ok_slot1  == 0    ||
             table->bsw_image_ok_slot1  == state_slot1.image_ok)) {

            return table->bsw_swap_type;
        }
    }

    return BOOT_SWAP_TYPE_NONE;
}

/**
 * Marks the image in slot 1 as pending.  On the next reboot, the system will
 * perform a one-time boot of the slot 1 image.
 *
 * @param permanent         Whether the image should be used permanently or
 *                              only tested once:
 *                                  0=run image once, then confirm or revert.
 *                                  1=run image forever.
 *
 * @return                  0 on success; nonzero on failure.
 */
int
boot_set_pending(int permanent)
{
    const struct flash_area *fap;
    struct boot_swap_state state_slot1;
    int area_id;
    int rc;

    rc = boot_read_swap_state_img(1, &state_slot1);
    if (rc != 0) {
        return rc;
    }

    switch (state_slot1.magic) {
    case BOOT_MAGIC_GOOD:
        /* Swap already scheduled. */
        return 0;

    case BOOT_MAGIC_UNSET:
        area_id = flash_area_id_from_image_slot(1);
        rc = flash_area_open(area_id, &fap);
        if (rc != 0) {
            rc = BOOT_EFLASH;
        } else {
            rc = boot_write_magic(fap);
        }

        if (rc == 0 && permanent) {
            rc = boot_write_image_ok(fap);
        }

        flash_area_close(fap);
        return rc;

    default:
        /* XXX: Temporary assert. */
        assert(0);
        return -1;
    }
}

/**
 * Marks the image in slot 0 as confirmed.  The system will continue booting into the image in slot 0 until told to boot from a different slot.
 *
 * @return                  0 on success; nonzero on failure.
 */
int
boot_set_confirmed(void)
{
    const struct flash_area *fap;
    struct boot_swap_state state_slot0;
    int rc;

    rc = boot_read_swap_state_img(0, &state_slot0);
    if (rc != 0) {
        return rc;
    }

    switch (state_slot0.magic) {
    case BOOT_MAGIC_GOOD:
        /* Confirm needed; proceed. */
        break;

    case BOOT_MAGIC_UNSET:
        /* Already confirmed. */
        return 0;

    case BOOT_MAGIC_BAD:
        /* Unexpected state. */
        return BOOT_EBADVECT;
    }

    if (state_slot0.copy_done == 0xff) {
        /* Swap never completed.  This is unexpected. */
        return BOOT_EBADVECT;
    }

    if (state_slot0.image_ok != 0xff) {
        /* Already confirmed. */
        return 0;
    }

    rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap);
    if (rc) {
        rc = BOOT_EFLASH;
        goto done;
    }

    rc = boot_write_image_ok(fap);
    if (rc != 0) {
        goto done;
    }

    rc = 0;

done:
    flash_area_close(fap);
    return rc;
}
