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

/** Internal flash layout. */
struct flash_area boot_test_area_descs[] = {
    [0] = { .fa_off = 0x00020000, .fa_size = 128 * 1024 },
    [1] = { .fa_off = 0x00040000, .fa_size = 128 * 1024 },
    [2] = { .fa_off = 0x00060000, .fa_size = 128 * 1024 },
    [3] = { .fa_off = 0x00080000, .fa_size = 128 * 1024 },
    [4] = { .fa_off = 0x000a0000, .fa_size = 128 * 1024 },
    [5] = { .fa_off = 0x000c0000, .fa_size = 128 * 1024 },
    [6] = { .fa_off = 0x000e0000, .fa_size = 128 * 1024 },
    [7] = { 0 },
};

/** Areas representing the beginning of image slots. */
uint8_t boot_test_slot_areas[] = {
    0, 3,
};

/** Flash offsets of the two image slots. */
struct boot_test_img_addrs boot_test_img_addrs[] = {
    { 0, 0x20000 },
    { 0, 0x80000 },
};

#define BOOT_TEST_AREA_IDX_SCRATCH 6

uint8_t
boot_test_util_byte_at(int img_msb, uint32_t image_offset)
{
    uint32_t u32;
    uint8_t *u8p;

    TEST_ASSERT(image_offset < 0x01000000);
    u32 = image_offset + (img_msb << 24);
    u8p = (void *)&u32;
    return u8p[image_offset % 4];
}

uint8_t
boot_test_util_flash_align(void)
{
    const struct flash_area *fap;
    int rc;

    rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap);
    TEST_ASSERT_FATAL(rc == 0);

    return flash_area_align(fap);
}

void
boot_test_util_init_flash(void)
{
    const struct flash_area *area_desc;
    int rc;

    rc = hal_flash_init();
    TEST_ASSERT(rc == 0);

    for (area_desc = boot_test_area_descs;
         area_desc->fa_size != 0;
         area_desc++) {

        rc = flash_area_erase(area_desc, 0, area_desc->fa_size);
        TEST_ASSERT(rc == 0);
    }
}

void
boot_test_util_copy_area(int from_area_idx, int to_area_idx)
{
    const struct flash_area *from_area_desc;
    const struct flash_area *to_area_desc;
    void *buf;
    int rc;

    from_area_desc = boot_test_area_descs + from_area_idx;
    to_area_desc = boot_test_area_descs + to_area_idx;

    TEST_ASSERT(from_area_desc->fa_size == to_area_desc->fa_size);

    buf = malloc(from_area_desc->fa_size);
    TEST_ASSERT(buf != NULL);

    rc = flash_area_read(from_area_desc, 0, buf,
                         from_area_desc->fa_size);
    TEST_ASSERT(rc == 0);

    rc = flash_area_erase(to_area_desc,
                          0,
                          to_area_desc->fa_size);
    TEST_ASSERT(rc == 0);

    rc = flash_area_write(to_area_desc, 0, buf,
                          to_area_desc->fa_size);
    TEST_ASSERT(rc == 0);

    free(buf);
}

static uint32_t
boot_test_util_area_write_size(int dst_idx, uint32_t off, uint32_t size)
{
    const struct flash_area *desc;
    int64_t diff;
    uint32_t trailer_start;
    uint8_t elem_sz;

    if (dst_idx != BOOT_TEST_AREA_IDX_SCRATCH - 1) {
        return size;
    }

    /* Don't include trailer in copy to second slot. */
    desc = boot_test_area_descs + dst_idx;
    elem_sz = boot_test_util_flash_align();
    trailer_start = desc->fa_size - boot_trailer_sz(elem_sz);
    diff = off + size - trailer_start;
    if (diff > 0) {
        if (diff > size) {
            size = 0;
        } else {
            size -= diff;
        }
    }

    return size;
}

void
boot_test_util_swap_areas(int area_idx1, int area_idx2)
{
    const struct flash_area *area_desc1;
    const struct flash_area *area_desc2;
    uint32_t size;
    void *buf1;
    void *buf2;
    int rc;

    area_desc1 = boot_test_area_descs + area_idx1;
    area_desc2 = boot_test_area_descs + area_idx2;

    TEST_ASSERT(area_desc1->fa_size == area_desc2->fa_size);

    buf1 = malloc(area_desc1->fa_size);
    TEST_ASSERT(buf1 != NULL);

    buf2 = malloc(area_desc2->fa_size);
    TEST_ASSERT(buf2 != NULL);

    rc = flash_area_read(area_desc1, 0, buf1, area_desc1->fa_size);
    TEST_ASSERT(rc == 0);

    rc = flash_area_read(area_desc2, 0, buf2, area_desc2->fa_size);
    TEST_ASSERT(rc == 0);

    rc = flash_area_erase(area_desc1, 0, area_desc1->fa_size);
    TEST_ASSERT(rc == 0);

    rc = flash_area_erase(area_desc2, 0, area_desc2->fa_size);
    TEST_ASSERT(rc == 0);

    size = boot_test_util_area_write_size(area_idx1, 0, area_desc1->fa_size);
    rc = flash_area_write(area_desc1, 0, buf2, size);
    TEST_ASSERT(rc == 0);

    size = boot_test_util_area_write_size(area_idx2, 0, area_desc2->fa_size);
    rc = flash_area_write(area_desc2, 0, buf1, size);
    TEST_ASSERT(rc == 0);

    free(buf1);
    free(buf2);
}

void
boot_test_util_write_image(const struct image_header *hdr, int slot)
{
    uint32_t image_off;
    uint32_t off;
    uint8_t flash_id;
    uint8_t buf[256];
    int chunk_sz;
    int rc;
    int i;

    TEST_ASSERT(slot == 0 || slot == 1);

    flash_id = boot_test_img_addrs[slot].flash_id;
    off = boot_test_img_addrs[slot].address;

    rc = hal_flash_write(flash_id, off, hdr, sizeof *hdr);
    TEST_ASSERT(rc == 0);

    off += hdr->ih_hdr_size;

    image_off = 0;
    while (image_off < hdr->ih_img_size) {
        if (hdr->ih_img_size - image_off > sizeof buf) {
            chunk_sz = sizeof buf;
        } else {
            chunk_sz = hdr->ih_img_size - image_off;
        }

        for (i = 0; i < chunk_sz; i++) {
            buf[i] = boot_test_util_byte_at(slot, image_off + i);
        }

        rc = hal_flash_write(flash_id, off + image_off, buf, chunk_sz);
        TEST_ASSERT(rc == 0);

        image_off += chunk_sz;
    }
}


void
boot_test_util_write_hash(const struct image_header *hdr, int slot)
{
    uint8_t tmpdata[1024];
    uint8_t hash[32];
    int rc;
    uint32_t off;
    uint32_t blk_sz;
    uint32_t sz;
    mbedtls_sha256_context ctx;
    uint8_t flash_id;
    uint32_t addr;
    struct image_tlv tlv;

    mbedtls_sha256_init(&ctx);
    mbedtls_sha256_starts(&ctx, 0);

    flash_id = boot_test_img_addrs[slot].flash_id;
    addr = boot_test_img_addrs[slot].address;

    sz = hdr->ih_hdr_size + hdr->ih_img_size;
    for (off = 0; off < sz; off += blk_sz) {
        blk_sz = sz - off;
        if (blk_sz > sizeof(tmpdata)) {
            blk_sz = sizeof(tmpdata);
        }
        rc = hal_flash_read(flash_id, addr + off, tmpdata, blk_sz);
        TEST_ASSERT(rc == 0);
        mbedtls_sha256_update(&ctx, tmpdata, blk_sz);
    }
    mbedtls_sha256_finish(&ctx, hash);

    tlv.it_type = IMAGE_TLV_SHA256;
    tlv._pad = 0;
    tlv.it_len = sizeof(hash);

    memcpy(tmpdata, &tlv, sizeof tlv);
    memcpy(tmpdata + sizeof tlv, hash, sizeof hash);
    rc = hal_flash_write(flash_id, addr + off, tmpdata,
                         sizeof tlv + sizeof hash);
    TEST_ASSERT(rc == 0);
}

static void
boot_test_util_write_swap_state(int flash_area_id,
                                const struct boot_swap_state *state)
{
    const struct flash_area *fap;
    int rc;

    rc = flash_area_open(flash_area_id, &fap);
    TEST_ASSERT_FATAL(rc == 0);

    switch (state->magic) {
    case 0:
        break;

    case BOOT_MAGIC_GOOD:
        rc = boot_write_magic(fap);
        TEST_ASSERT_FATAL(rc == 0);
        break;

    default:
        TEST_ASSERT_FATAL(0);
        break;
    }

    if (state->copy_done != 0xff) {
        rc = boot_write_copy_done(fap);
        TEST_ASSERT_FATAL(rc == 0);
    }

    if (state->image_ok != 0xff) {
        rc = boot_write_image_ok(fap);
        TEST_ASSERT_FATAL(rc == 0);
    }
}

void
boot_test_util_mark_revert(void)
{
    struct boot_swap_state state_slot0 = {
        .magic = BOOT_MAGIC_GOOD,
        .copy_done = 0x01,
        .image_ok = 0xff,
    };

    boot_test_util_write_swap_state(FLASH_AREA_IMAGE_0, &state_slot0);
}

void
boot_test_util_mark_swap_perm(void)
{
    struct boot_swap_state state_slot0 = {
        .magic = BOOT_MAGIC_GOOD,
        .copy_done = 0x01,
        .image_ok = 0x01,
    };

    boot_test_util_write_swap_state(FLASH_AREA_IMAGE_0, &state_slot0);
}

void
boot_test_util_verify_area(const struct flash_area *area_desc,
                           const struct image_header *hdr,
                           uint32_t image_addr, int img_msb)
{
    struct image_header temp_hdr;
    uint32_t area_end;
    uint32_t img_size;
    uint32_t img_off;
    uint32_t img_end;
    uint32_t addr;
    uint8_t buf[256];
    int rem_area;
    int past_image;
    int chunk_sz;
    int rem_img;
    int rc;
    int i;

    addr = area_desc->fa_off;

    if (hdr != NULL) {
        img_size = hdr->ih_img_size;

        if (addr == image_addr) {
            rc = hal_flash_read(area_desc->fa_device_id, image_addr,
                                &temp_hdr, sizeof temp_hdr);
            TEST_ASSERT(rc == 0);
            TEST_ASSERT(memcmp(&temp_hdr, hdr, sizeof *hdr) == 0);

            addr += hdr->ih_hdr_size;
        }
    } else {
        img_size = 0;
    }

    area_end = area_desc->fa_off + area_desc->fa_size;
    img_end = image_addr + img_size;
    past_image = addr >= img_end;

    while (addr < area_end) {
        rem_area = area_end - addr;
        rem_img = img_end - addr;

        if (hdr != NULL) {
            img_off = addr - image_addr - hdr->ih_hdr_size;
        } else {
            img_off = 0;
        }

        if (rem_area > sizeof buf) {
            chunk_sz = sizeof buf;
        } else {
            chunk_sz = rem_area;
        }

        rc = hal_flash_read(area_desc->fa_device_id, addr, buf, chunk_sz);
        TEST_ASSERT(rc == 0);

        for (i = 0; i < chunk_sz; i++) {
            if (rem_img > 0) {
                TEST_ASSERT(buf[i] == boot_test_util_byte_at(img_msb,
                                                        img_off + i));
            } else if (past_image) {
#if 0
                TEST_ASSERT(buf[i] == 0xff);
#endif
            }
        }

        addr += chunk_sz;
    }
}


void
boot_test_util_verify_status_clear(void)
{
    struct boot_swap_state state_slot0;
    int rc;

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

    TEST_ASSERT(state_slot0.magic != BOOT_MAGIC_UNSET ||
                state_slot0.copy_done != 0);
}


void
boot_test_util_verify_flash(const struct image_header *hdr0, int orig_slot_0,
                            const struct image_header *hdr1, int orig_slot_1)
{
    const struct flash_area *area_desc;
    int area_idx;

    area_idx = 0;

    while (1) {
        area_desc = boot_test_area_descs + area_idx;
        if (area_desc->fa_off == boot_test_img_addrs[1].address &&
            area_desc->fa_device_id == boot_test_img_addrs[1].flash_id) {
            break;
        }

        boot_test_util_verify_area(area_desc, hdr0,
                                   boot_test_img_addrs[0].address, orig_slot_0);
        area_idx++;
    }

    while (1) {
        if (area_idx == BOOT_TEST_AREA_IDX_SCRATCH) {
            break;
        }

        area_desc = boot_test_area_descs + area_idx;
        boot_test_util_verify_area(area_desc, hdr1,
                                   boot_test_img_addrs[1].address, orig_slot_1);
        area_idx++;
    }
}

void
boot_test_util_verify_all(int expected_swap_type,
                          const struct image_header *hdr0,
                          const struct image_header *hdr1)
{
    const struct image_header *slot0hdr;
    const struct image_header *slot1hdr;
    struct boot_rsp rsp;
    int orig_slot_0;
    int orig_slot_1;
    int num_swaps;
    int rc;
    int i;

    TEST_ASSERT_FATAL(hdr0 != NULL || hdr1 != NULL);

    num_swaps = 0;
    for (i = 0; i < 3; i++) {
        rc = boot_go(&rsp);
        TEST_ASSERT_FATAL(rc == 0);

        if (expected_swap_type != BOOT_SWAP_TYPE_NONE) {
            num_swaps++;
        }

        if (num_swaps % 2 == 0) {
            if (hdr0 != NULL) {
                slot0hdr = hdr0;
                slot1hdr = hdr1;
            } else {
                slot0hdr = hdr1;
                slot1hdr = hdr0;
            }
            orig_slot_0 = 0;
            orig_slot_1 = 1;
        } else {
            if (hdr1 != NULL) {
                slot0hdr = hdr1;
                slot1hdr = hdr0;
            } else {
                slot0hdr = hdr0;
                slot1hdr = hdr1;
            }
            orig_slot_0 = 1;
            orig_slot_1 = 0;
        }

        TEST_ASSERT(memcmp(rsp.br_hdr, slot0hdr, sizeof *slot0hdr) == 0);
        TEST_ASSERT(rsp.br_flash_id == boot_test_img_addrs[0].flash_id);
        TEST_ASSERT(rsp.br_image_addr == boot_test_img_addrs[0].address);

        boot_test_util_verify_flash(slot0hdr, orig_slot_0,
                                    slot1hdr, orig_slot_1);
        boot_test_util_verify_status_clear();

        if (expected_swap_type != BOOT_SWAP_TYPE_NONE) {
            switch (expected_swap_type) {
            case BOOT_SWAP_TYPE_TEST:
                expected_swap_type = BOOT_SWAP_TYPE_REVERT;
                break;

            case BOOT_SWAP_TYPE_PERM:
                expected_swap_type = BOOT_SWAP_TYPE_NONE;
                break;

            case BOOT_SWAP_TYPE_REVERT:
                expected_swap_type = BOOT_SWAP_TYPE_NONE;
                break;

            default:
                TEST_ASSERT_FATAL(0);
                break;
            }
        }
    }
}
