/*
* Copyright (c) 2025 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#pragma once

#ifdef __cplusplus
#include <algorithm>
#include <memory>
#include <set>
#include <string>
#include <utility>
#endif

#include "boot/uf2.h"
#include "boot/picoboot.h"

// Unreadable ROM data
#include "rp2350_a2_rom_end.h"
#include "rp2350_a3_rom_end.h"
#include "rp2350_a4_rom_end.h"

// tsk namespace is polluted on windows
#ifdef _WIN32
#undef min
#undef max

#define _CRT_SECURE_NO_WARNINGS
#endif

enum memory_type {
    rom,
    flash,
    sram,
    sram_unstriped,
    xip_sram,
    invalid,
};

typedef enum {
    rp2040,
    rp2350,
    unknown
} chip_t;

typedef enum {
    rp2040_b0,
    rp2040_b1,
    rp2040_b2,
    rp2350_a2,
    rp2350_a3,
    rp2350_a4,
    unknown_revision
} chip_revision_t;

#ifdef __cplusplus
#include "addresses.h"
#include "errors.h"

static std::string chip_name(chip_t chip) {
    std::string device = "RP-series";
    if (chip == rp2040) {
        device = "RP2040";
    } else if (chip == rp2350) {
        device = "RP2350";
    }
    return device;

}

// details of a specific chip/version. the most fleshed out version is derived from an actual device connection (usually by
// looking at the bootrom), however "stock" versions can be created from family IDs for example
class model_info {
public:
    model_info(chip_t chip, std::string name, uint32_t rom_end, std::set<picoboot_cmd_id> picoboot_cmds = {}) : _chip(chip), _name(std::move(name)),
        _rom_end(rom_end), _picoboot_cmds(std::move(picoboot_cmds)) {}
    chip_t chip() const { return _chip; }
    chip_revision_t chip_revision() const { return _chip_revision; }
    void set_chip_revision(chip_revision_t revision) { _chip_revision = revision; }
    uint32_t family_id() const { return _family_id; }
    void set_family_id(uint32_t family_id) { _family_id = family_id; }
    uint32_t rom_start() const { return ROM_START; }
    uint32_t rom_end() const { return _rom_end; }
    virtual enum memory_type get_memory_type(uint32_t addr) {
        if (addr >= rom_start() && addr <= rom_end()) {
            return rom;
        }
        return invalid;
    }

    virtual bool supports_picoboot_cmd(picoboot_cmd_id cmd) const {
        return _picoboot_cmds.find(cmd) != _picoboot_cmds.end();
    }

    virtual bool supports_picoboot_cmd(picoboot_cmd_id cmd, std::string& failed_device_name) const {
        if (!supports_picoboot_cmd(cmd)) {
            failed_device_name = name();
            return false;
        }
        return true;
    }
    bool supports_picoboot_cmds(std::set<picoboot_cmd_id> cmds, std::string& failed_device_name) const {
        for (auto cmd : cmds) {
            if (!supports_picoboot_cmd(cmd, failed_device_name)) {
                return false;
            }
        }
        return true;
    }
    std::string name() const { return _name; }
    virtual std::string revision_name() const {
        return "Unknown";
    }

    virtual bool supports_partition_table() { return false; }
    virtual bool supports_otp_v2() { return false; }
    virtual bool requires_block_loop() { return false; }
    virtual int rom_table_version() { fail(ERROR_NOT_POSSIBLE, "unknown rom table version"); return 0; }
    virtual uint32_t flash_start() { fail(ERROR_NOT_POSSIBLE, "unknown flash start"); return 0; }
    virtual uint32_t flash_end() { fail(ERROR_NOT_POSSIBLE, "unknown flash end"); return 0; }
    virtual uint32_t sram_start() { fail(ERROR_NOT_POSSIBLE, "unknown sram start"); return 0; }
    virtual uint32_t sram_end() { fail(ERROR_NOT_POSSIBLE, "unknown sram end"); return 0; }
    virtual uint32_t xip_sram_start() { fail(ERROR_NOT_POSSIBLE, "unknown xip sram start"); return 0; }
    virtual uint32_t xip_sram_end() { fail(ERROR_NOT_POSSIBLE, "unknown xip sram end"); return 0; }
    virtual uint32_t unreadable_rom_start() { return 0xffffffff; }
    virtual uint32_t unreadable_rom_end() { return 0xffffffff; }
    virtual const unsigned char *unreadable_rom_data() { return nullptr; }
private:
    std::string _name;
    chip_revision_t _chip_revision;
    uint32_t _rom_end;
    std::set<picoboot_cmd_id> _picoboot_cmds;
    chip_t _chip;
    uint32_t _family_id;
};

class model_unknown : public model_info {
public:
    // note we allow a small amount of ROM so that we can read the id bytes
    model_unknown() : model_info(unknown, chip_name(unknown), 0x100) {

    }
};

class model_rp : public model_info {
protected:
    model_rp(chip_t chip, std::string name, uint32_t rom_end, std::set<picoboot_cmd_id> picoboot_cmds = {}) : model_info(chip, std::move(name), rom_end, std::move(picoboot_cmds)) {}

public:
    enum memory_type get_memory_type(uint32_t addr) override {
        if (addr >= flash_start() && addr <= flash_end()) {
            return flash;
        }
        if (addr >= sram_start() && addr <= sram_end()) {
            return sram;
        }
        if (addr >= xip_sram_start() && addr <= xip_sram_end()) {
            return xip_sram;
        }
        return model_info::get_memory_type(addr);
    }

    uint32_t sram_start() override {
        return SRAM_START;
    }

    uint32_t flash_start() override {
        return FLASH_START;
    }

};

class model_rp_generic : public model_rp {
public:
    // allow large memory regions for generic model
    model_rp_generic() : model_rp(unknown, chip_name(unknown), 0x100, {}) {}

    uint32_t xip_sram_start() override {
        return std::min({XIP_SRAM_START_RP2040, XIP_SRAM_START_RP2350});
    }

    uint32_t xip_sram_end() override {
        return std::max({XIP_SRAM_END_RP2040, XIP_SRAM_END_RP2350});
    }

    uint32_t sram_end() override {
        return std::max({SRAM_END_RP2040, SRAM_END_RP2350});
    }

    uint32_t flash_end() override {
        return std::max({FLASH_END_RP2040, FLASH_END_RP2350});
    }
};

class model_rp2040 : public model_rp {
public:
    model_rp2040() : model_rp(rp2040, chip_name(rp2040), ROM_END_RP2040, {
                PC_EXCLUSIVE_ACCESS,
                PC_REBOOT,
                PC_FLASH_ERASE,
                PC_READ,
                PC_WRITE,
                PC_EXIT_XIP,
                PC_ENTER_CMD_XIP,
                PC_EXEC,
                PC_VECTORIZE_FLASH,
            }) {
                set_family_id(RP2040_FAMILY_ID);
            }

    enum memory_type get_memory_type(uint32_t addr) override {
        if (addr >= MAIN_RAM_BANKED_START && addr <= MAIN_RAM_BANKED_END) {
            return sram_unstriped;
        }
        return model_rp::get_memory_type(addr);
    }

    int rom_table_version() override {
        return 1;
    }

    uint32_t xip_sram_start() override {
        return XIP_SRAM_START_RP2040;
    }

    uint32_t xip_sram_end() override {
        return XIP_SRAM_END_RP2040;
    }

    uint32_t sram_end() override {
        return SRAM_END_RP2040;
    }

    uint32_t flash_end() override {
        return FLASH_END_RP2040;
    }

    virtual std::string revision_name() const override{
        switch (chip_revision()) {
            case rp2040_b0:
                return "B0";
            case rp2040_b1:
                return "B1";
            case rp2040_b2:
                return "B2";
            default:
                return model_rp::revision_name();
        }
    }

};

class model_rp2350 : public model_rp {
public:
    model_rp2350() : model_rp2350(ROM_END_RP2350) {}
    explicit model_rp2350(uint32_t rom_end) : model_rp(rp2350, rom_end > 0x8000 ? "RP2350(64k)" : "RP2350", rom_end, {
        PC_EXCLUSIVE_ACCESS,
        PC_REBOOT,
        PC_FLASH_ERASE,
        PC_READ,
        PC_WRITE,
        PC_EXIT_XIP,
        PC_ENTER_CMD_XIP,
        PC_EXEC,
        PC_REBOOT2,
        PC_GET_INFO,
        PC_OTP_READ,
        PC_OTP_WRITE,
    }) {}

    bool supports_partition_table() override { return true; }
    bool requires_block_loop() override { return true; }

    int rom_table_version() override {
        return 2;
    }

    uint32_t xip_sram_start() override {
        return XIP_SRAM_START_RP2350;
    }

    uint32_t xip_sram_end() override {
        return XIP_SRAM_END_RP2350;
    }

    uint32_t sram_end() override {
        return SRAM_END_RP2350;
    }

    uint32_t flash_end() override {
        return FLASH_END_RP2350;
    }

    uint32_t unreadable_rom_start() override {
        return rom_end() - 0x200;
    }

    uint32_t unreadable_rom_end() override {
        return rom_end();
    }

    const unsigned char *unreadable_rom_data() override {
        switch (chip_revision()) {
            case rp2350_a2:
                return rp2350_a2_rom_end;
            case rp2350_a3:
                return rp2350_a3_rom_end;
            case rp2350_a4:
                return rp2350_a4_rom_end;
            default:
                return nullptr;
        }
    }

    virtual std::string revision_name() const override{
        switch (chip_revision()) {
            case rp2350_a2:
                return "A2";
            case rp2350_a3:
                return "A3";
            case rp2350_a4:
                return "A4";
            default:
                return model_rp::revision_name();
        }
    }
};

class model_rp2350_arm_s : public model_rp2350 {
public:
    model_rp2350_arm_s() : model_rp2350() {
        set_family_id(RP2350_ARM_S_FAMILY_ID);
    }
};

class model_rp2350_arm_ns : public model_rp2350 {
public:
    model_rp2350_arm_ns() : model_rp2350() {
        set_family_id(RP2350_ARM_NS_FAMILY_ID);
    }
};

class model_rp2350_riscv : public model_rp2350 {
public:
    model_rp2350_riscv() : model_rp2350() {
        set_family_id(RP2350_RISCV_FAMILY_ID);
    }
};

struct models {
    static std::shared_ptr<model_info> unknown;
    static std::shared_ptr<model_info> largest;
};

typedef std::shared_ptr<model_info> model_t;

// inclusive of ends
static inline enum memory_type get_memory_type(uint32_t addr, const model_t& model) {
    return model->get_memory_type(addr);
}

static model_t model_from_family(uint32_t family_id) {
    if (family_id == RP2040_FAMILY_ID) {
        return std::make_shared<model_rp2040>();
    } else if (family_id >= RP2350_ARM_S_FAMILY_ID && family_id <= RP2350_ARM_NS_FAMILY_ID) {
        return std::make_shared<model_rp2350>();
    }
    return models::unknown;
}

// const address_ranges rp2040_address_ranges_flash {
//     address_range(FLASH_START, FLASH_END_RP2040, address_range::type::CONTENTS),
//     address_range(SRAM_START, SRAM_END_RP2040, address_range::type::NO_CONTENTS),
//     address_range(MAIN_RAM_BANKED_START, MAIN_RAM_BANKED_END, address_range::type::NO_CONTENTS)
// };
//
// const address_ranges rp2350_address_ranges_flash {
//     address_range(FLASH_START, FLASH_END_RP2350, address_range::type::CONTENTS),
//     address_range(SRAM_START, SRAM_END_RP2350, address_range::type::NO_CONTENTS),
//     address_range(MAIN_RAM_BANKED_START, MAIN_RAM_BANKED_END, address_range::type::NO_CONTENTS)
// };


static address_ranges address_ranges_flash(const model_t& model) {
    address_ranges ranges;
    ranges.emplace_back(model->flash_start(), model->flash_end(), address_range::type::CONTENTS);
    ranges.emplace_back(model->sram_start(), model->sram_end(), address_range::type::NO_CONTENTS);
    ranges.emplace_back(model->xip_sram_start(), model->xip_sram_end(), address_range::type::NO_CONTENTS);
    if (model->chip() == rp2040) {
        ranges.emplace_back(MAIN_RAM_BANKED_START, MAIN_RAM_BANKED_END, address_range::type::NO_CONTENTS);
    }
    return ranges;
}


//
// const address_ranges rp2040_address_ranges_ram {
//     address_range(SRAM_START, SRAM_END_RP2040, address_range::type::CONTENTS),
//     address_range(XIP_SRAM_START_RP2040, XIP_SRAM_END_RP2040, address_range::type::CONTENTS),
//     address_range(ROM_START, ROM_END_RP2040, address_range::type::IGNORE) // for now we ignore the bootrom if present
// };
//
// const address_ranges rp2350_address_ranges_ram {
//     address_range(SRAM_START, SRAM_END_RP2350, address_range::type::CONTENTS),
//     address_range(XIP_SRAM_START_RP2350, XIP_SRAM_END_RP2350, address_range::type::CONTENTS),
//     address_range(ROM_START, ROM_END_RP2350, address_range::type::IGNORE) // for now we ignore the bootrom if present
// };

static address_ranges address_ranges_ram(const model_t& model) {
    address_ranges ranges;
    ranges.emplace_back(model->sram_start(), model->sram_end(), address_range::type::CONTENTS);
    ranges.emplace_back(model->xip_sram_start(), model->xip_sram_end(), address_range::type::CONTENTS);
    ranges.emplace_back(model->rom_start(), model->rom_end(), address_range::type::IGNORE);
    return ranges;
}

static bool contains_unreadable_rom(uint32_t addr, uint32_t size, const model_t& model) {
    return (addr >= model->unreadable_rom_start() && addr < model->unreadable_rom_end()) ||
            (addr + size > model->unreadable_rom_start() && addr + size <= model->unreadable_rom_end()) ||
            (addr < model->unreadable_rom_start() && addr + size > model->unreadable_rom_end());
}

#endif