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

#include "os/mynewt.h"
#include "hal/hal_bsp.h"
#include "hal/hal_flash.h"
#include "hal/hal_flash_int.h"

int
hal_flash_init(void)
{
    const struct hal_flash *hf;
    uint8_t i;
    int rc = 0;

    for (i = 0; ; i++) {
        hf = hal_bsp_flash_dev(i);
        if (!hf) {
            break;
        }
        if (hf->hf_itf->hff_init(hf)) {
            rc = -1;
        }
    }
    return rc;
}

uint8_t
hal_flash_align(uint8_t flash_id)
{
    const struct hal_flash *hf;

    hf = hal_bsp_flash_dev(flash_id);
    if (!hf) {
        return 1;
    }
    return hf->hf_align;
}

uint8_t
hal_flash_erased_val(uint8_t flash_id)
{
    const struct hal_flash *hf;

    hf = hal_bsp_flash_dev(flash_id);
    if (!hf) {
        return 1;
    }
    return hf->hf_erased_val;
}

uint32_t
hal_flash_sector_size(const struct hal_flash *hf, int sec_idx)
{
    uint32_t size;
    uint32_t start;

    if (hf->hf_itf->hff_sector_info(hf, sec_idx, &start, &size)) {
        return 0;
    }
    return size;
}

static int
hal_flash_check_addr(const struct hal_flash *hf, uint32_t addr)
{
    if (addr < hf->hf_base_addr || addr > hf->hf_base_addr + hf->hf_size) {
        return -1;
    }
    return 0;
}

int
hal_flash_read(uint8_t id, uint32_t address, void *dst, uint32_t num_bytes)
{
    const struct hal_flash *hf;

    hf = hal_bsp_flash_dev(id);
    if (!hf) {
        return -1;
    }
    if (hal_flash_check_addr(hf, address) ||
      hal_flash_check_addr(hf, address + num_bytes)) {
        return -1;
    }
    return hf->hf_itf->hff_read(hf, address, dst, num_bytes);
}

#if MYNEWT_VAL(HAL_FLASH_VERIFY_WRITES)
/**
 * Verifies that the specified range of flash contains the given contents.
 *
 * @return                      0 on success;
 *                              nonzero on error or unexpected contents.
 */
static int
hal_flash_cmp(const struct hal_flash *hf, uint32_t address, const void *val,
  uint32_t num_bytes)
{
    uint8_t buf[MYNEWT_VAL(HAL_FLASH_VERIFY_BUF_SZ)];

    const uint8_t *u8p;
    uint32_t off;
    uint32_t rem;
    int chunk_sz;
    int rc;

    u8p = val;

    for (off = 0; off < num_bytes; off += sizeof buf) {
        rem = num_bytes - off;
        if (rem >= sizeof buf) {
            chunk_sz = sizeof buf;
        } else {
            chunk_sz = rem;
        }

        rc = hf->hf_itf->hff_read(hf, address + off, buf, chunk_sz);
        if (rc != 0) {
            return rc;
        }

        if (memcmp(buf, u8p + off, chunk_sz) != 0) {
            return -1;
        }
    }

    return 0;
}
#endif

int
hal_flash_write(uint8_t id, uint32_t address, const void *src,
  uint32_t num_bytes)
{
    const struct hal_flash *hf;
    int rc;

    hf = hal_bsp_flash_dev(id);
    if (!hf) {
        return -1;
    }
    if (hal_flash_check_addr(hf, address) ||
      hal_flash_check_addr(hf, address + num_bytes)) {
        return -1;
    }

    rc = hf->hf_itf->hff_write(hf, address, src, num_bytes);
    if (rc != 0) {
        return rc;
    }

#if MYNEWT_VAL(HAL_FLASH_VERIFY_WRITES)
    assert(hal_flash_cmp(hf, address, src, num_bytes) == 0);
#endif

    return 0;
}

int
hal_flash_erase_sector(uint8_t id, uint32_t sector_address)
{
    const struct hal_flash *hf;
    uint32_t start;
    uint32_t size;
    int rc;
    int i;

    (void) start;
    (void) size;
    (void) i;

    hf = hal_bsp_flash_dev(id);
    if (!hf) {
        return -1;
    }
    if (hal_flash_check_addr(hf, sector_address)) {
        return -1;
    }

    rc = hf->hf_itf->hff_erase_sector(hf, sector_address);
    if (rc != 0) {
        return rc;
    }

#if MYNEWT_VAL(HAL_FLASH_VERIFY_ERASES)
    /* Find the sector bounds so we can verify the erase. */
    for (i = 0; i < hf->hf_sector_cnt; i++) {
        rc = hf->hf_itf->hff_sector_info(hf, i, &start, &size);
        assert(rc == 0);

        if (sector_address == start) {
            assert(hal_flash_isempty_no_buf(id, start, size) == 1);
            break;
        }
    }
#endif

    return 0;
}

int
hal_flash_erase(uint8_t id, uint32_t address, uint32_t num_bytes)
{
    const struct hal_flash *hf;
    uint32_t start, size;
    uint32_t end;
    uint32_t end_area;
    int i;
    int rc;

    hf = hal_bsp_flash_dev(id);
    if (!hf) {
        return -1;
    }
    if (hal_flash_check_addr(hf, address) ||
      hal_flash_check_addr(hf, address + num_bytes)) {
        return -1;
    }

    end = address + num_bytes;
    if (end <= address) {
        /*
         * Check for wrap-around.
         */
        return -1;
    }

    for (i = 0; i < hf->hf_sector_cnt; i++) {
        rc = hf->hf_itf->hff_sector_info(hf, i, &start, &size);
        assert(rc == 0);
        end_area = start + size;
        if (address < end_area && end > start) {
            /*
             * If some region of eraseable area falls inside sector,
             * erase the sector.
             */
            if (hf->hf_itf->hff_erase_sector(hf, start)) {
                return -1;
            }

#if MYNEWT_VAL(HAL_FLASH_VERIFY_ERASES)
            assert(hal_flash_isempty_no_buf(id, start, size) == 1);
#endif
        }
    }
    return 0;
}

int
hal_flash_is_erased(const struct hal_flash *hf, uint32_t address, void *dst,
        uint32_t num_bytes)
{
    uint32_t i;
    uint8_t *buf;

    buf = dst;

    if (hf->hf_itf->hff_read(hf, address, dst, num_bytes)) {
        return -1;
    }
    for (i = 0; i < num_bytes; i++) {
        if (buf[i] != hf->hf_erased_val) {
            return 0;
        }
    }
    return 1;
}

int
hal_flash_isempty(uint8_t id, uint32_t address, void *dst, uint32_t num_bytes)
{
    const struct hal_flash *hf;

    hf = hal_bsp_flash_dev(id);
    if (!hf) {
        return -1;
    }
    if (hal_flash_check_addr(hf, address) ||
      hal_flash_check_addr(hf, address + num_bytes)) {
        return -1;
    }
    if (hf->hf_itf->hff_is_empty) {
        return hf->hf_itf->hff_is_empty(hf, address, dst, num_bytes);
    } else {
        return hal_flash_is_erased(hf, address, dst, num_bytes);
    }
}

int
hal_flash_isempty_no_buf(uint8_t id, uint32_t address, uint32_t num_bytes)
{
    uint8_t buf[MYNEWT_VAL(HAL_FLASH_VERIFY_BUF_SZ)];
    uint32_t blksz;
    uint32_t rem;
    uint32_t off;
    int empty;

    for (off = 0; off < num_bytes; off += sizeof buf) {
        rem = num_bytes - off;

        blksz = sizeof buf;
        if (blksz > rem) {
            blksz = rem;
        }

        empty = hal_flash_isempty(id, address + off, buf, blksz);
        if (empty != 1) {
            return empty;
        }
    }

    return 1;
}

int
hal_flash_ioctl(uint8_t id, uint32_t cmd, void *args)
{
    return 0;
}
