#include "NVMeError.hpp"
#include "NVMeIntf.hpp"

#include <boost/asio.hpp>
#include <boost/endian.hpp>
#include <phosphor-logging/lg2.hpp>

#include <thread>

struct ListNode
{
    ListNode *next, *prev;
};

struct nvme_mi_ctrl
{
    void* ep;
    __u16 id;
    ListNode ep_entry;
};

class NVMeMiFake :
    public NVMeMiIntf,
    public std::enable_shared_from_this<NVMeMiFake>
{
  public:
    NVMeMiFake(boost::asio::io_context& io, std::chrono::milliseconds delay) :
        io(io), valid(true) /*, worker(workerIO.get_executor())*/
    {
        // start worker thread
        thread = std::thread([&io = workerIO, &stop = workerStop,
                              &mtx = workerMtx, &cv = workerCv,
                              &isNotified = workerIsNotified, delay]() {
            lg2::info("NVMeMiFake worker thread started: {STOPPED}", "STOPPED",
                      io.stopped());
            // With BOOST_ASIO_DISABLE_THREADS, boost::asio::executor_work_guard
            // issues null_event across the thread, which caused invalid
            // invokation. We implement a simple invoke machenism based
            // std::condition_variable.
            io.stop();
            io.restart();
            while (true)
            {
                // mimik the communication delay.
                std::this_thread::sleep_for(delay);
                io.run();
                io.restart();
                lg2::info("job done");
                {
                    std::unique_lock<std::mutex> lock(mtx);
                    cv.wait(lock, [&]() { return isNotified; });
                    isNotified = false;
                    if (stop)
                    {
                        // exhaust all tasks and exit
                        io.run();
                        break;
                    }
                }
            }
            lg2::error("NVMeMi worker this line should not be reached");
        });

        ctrls.resize(3);
        lg2::info("NVMeMiFake constructor");
    }

    ~NVMeMiFake() override
    {
        if (valid)
        {
            lg2::info("NVMeMiFake destroyer");
        }
        else
        {
            lg2::info("NVMeMiFake default destroyer");
        }

        // close worker
        workerStop = true;
        {
            std::unique_lock<std::mutex> lock(workerMtx);
            workerIsNotified = true;
            workerCv.notify_all();
        }
        thread.join();
    }

    void start(const std::shared_ptr<MctpEndpoint>& endpoint
               [[maybe_unused]]) override
    {}
    void stop() override {}
    void recover() override {}

    void miSubsystemHealthStatusPoll(
        std::function<void(const std::error_code&,
                           nvme_mi_nvm_ss_health_status*)>&& cb) override
    {
        boost::asio::post(io, [cb{std::move(cb)}]() {
            nvme_mi_nvm_ss_health_status status{};
            status.nss = 1 << 5;
            status.ctemp = 24;
            cb({}, &status);
        });
    }

    void miScanCtrl(std::function<void(const std::error_code&,
                                       const std::vector<nvme_mi_ctrl_t>&)>
                        cb) override
    {
        if (workerStop)
        {
            lg2::error("worker thread for nvme endpoint is stopped");

            boost::asio::post(io, [cb{std::move(cb)}]() {
                cb(std::make_error_code(std::errc::no_such_device), {});
            });
            return;
        }

        post([self{shared_from_this()}, cb = std::move(cb)] {
            lg2::info("libnvme: scan");
            boost::asio::post(
                self->io, [self{self->shared_from_this()}, cb{cb}]() mutable {
                auto& ctrl1 = self->ctrls[0];
                auto& ctrl2 = self->ctrls[1];
                auto& ctrl3 = self->ctrls[2];
                ctrl1.id = 0;
                ctrl2.id = 1;
                ctrl3.id = 2;
                std::vector<nvme_mi_ctrl_t> list{&ctrl1, &ctrl2, &ctrl3};
                cb({}, list);
            });
        });
    }

    bool flushOperations(std::function<void()>&& cb) override
    {
        post([self{shared_from_this()}, cb{std::move(cb)}]() {
            boost::asio::post(self->io, cb);
        });
        return true;
    }

    void adminIdentify(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl, nvme_identify_cns cns,
        [[maybe_unused]] uint32_t nsid, [[maybe_unused]] uint16_t cntid,
        std::function<void(nvme_ex_ptr, std::span<uint8_t>)>&& cb) override
    {
        lg2::info("identify");
        post([self{shared_from_this()}, cb = std::move(cb), cns, nsid]() {
            lg2::info("libnvme: identify");
            boost::asio::post(self->io, [cb{cb}, cns, nsid]() mutable {
                std::vector<uint8_t> data;
                switch (cns)
                {
                    case NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST:
                    {
                        nvme_secondary_ctrl_list list{};
                        list.num = 2;
                        list.sc_entry[0].pcid = 0;
                        list.sc_entry[0].scid = 1;
                        list.sc_entry[0].scs = 1;
                        list.sc_entry[1].pcid = 0;
                        list.sc_entry[1].scid = 2;
                        list.sc_entry[1].scs = 0;
                        data.resize(sizeof(nvme_secondary_ctrl_list));
                        memcpy(data.data(), &list, data.size());
                        break;
                    }
                    case NVME_IDENTIFY_CNS_NS_CTRL_LIST:
                    {
                        nvme_ctrl_list ctrlList{};
                        ctrlList.num = 1;
                        ctrlList.identifier[0] = 0;
                        if (nsid == 1)
                        {
                            ctrlList.num++;
                            ctrlList.identifier[1] = 1;
                        }
                        data.resize(sizeof(ctrlList));
                        memcpy(data.data(), &ctrlList, data.size());
                        break;
                    }
                    default:
                        data.resize(NVME_IDENTIFY_DATA_SIZE);
                }
                cb({}, std::span<uint8_t>(data.begin(), data.size()));
            });
        });
    }
    void adminGetFeatures([[maybe_unused]] nvme_mi_ctrl_t ctrl,
                          [[maybe_unused]] const GetFeaturesRequest& req,
                          std::function<void(nvme_ex_ptr, uint32_t,
                                             std::span<uint8_t>)>&& cb) override
    {
        boost::asio::post(io, [cb = std::move(cb)]() mutable {
            cb(makeLibNVMeError("not supported"), 0, {});
        });
    }

    void adminSetFeatures(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl,
        [[maybe_unused]] const SetFeaturesRequest& req,
        std::function<void(nvme_ex_ptr, uint32_t)>&& cb) override
    {
        boost::asio::post(io, [cb = std::move(cb)]() mutable {
            cb(makeLibNVMeError("not supported"), 0);
        });
    }

    void adminGetLogPage(
        nvme_mi_ctrl_t /*ctrl*/, nvme_cmd_get_log_lid lid, uint32_t /*nsid*/,
        uint8_t lsp, uint16_t /*lsi*/,
        std::function<void(const std::error_code&, std::span<uint8_t>)>&& cb,
        uint8_t /*dataArea*/) override
    {
        try
        {
            post([lid, lsp, self{shared_from_this()}, cb{std::move(cb)}]() {
                int rc = 0;
                std::vector<uint8_t> data;
                try
                {
                    switch (lid)
                    {
                        case NVME_LOG_LID_TELEMETRY_HOST:
                        {
                            data.resize(sizeof(nvme_telemetry_log));
                            nvme_telemetry_log& log =
                                // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                                *reinterpret_cast<nvme_telemetry_log*>(
                                    data.data());
                            if (lsp == NVME_LOG_TELEM_HOST_LSP_CREATE)
                            {
                                log.lpi = 0x07;
                                if (rc != 0)
                                {
                                    lg2::error(
                                        "failed to create telemetry host log");
                                    throw std::system_error(
                                        errno, std::generic_category());
                                }
                            }
                            else if (lsp == NVME_LOG_TELEM_HOST_LSP_RETAIN)
                            {
                                // nvme rev 1.3 only applies upto Area 3
                                log.dalb1 = 512;
                                log.dalb2 = 512;
                                log.dalb3 = 512;
                                log.dalb4 = 512;
                                data.resize(sizeof(nvme_telemetry_log) + 512);
                                std::string str = "hello world";
                                for (std::size_t i = 0; i < str.size(); i++)
                                {
                                    data[sizeof(nvme_telemetry_log) + i] =
                                        static_cast<uint8_t>(str[i]);
                                }

                                if (rc != 0)
                                {
                                    lg2::error(
                                        "failed to retain telemetry host log full log");
                                    throw std::system_error(
                                        errno, std::generic_category());
                                }
                            }
                            else
                            {
                                throw std::system_error(std::make_error_code(
                                    std::errc::invalid_argument));
                            }
                        }
                        break;
                        case NVME_LOG_LID_SMART:
                        {
                            data.resize(sizeof(nvme_smart_log));
                            nvme_smart_log& log =
                                // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                                *reinterpret_cast<nvme_smart_log*>(data.data());
                            uint8_t temp = 40;
                            log.temperature[0] = temp;
                            log.temperature[1] = 1;
                            break;
                        }
                        case NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN:
                        {
                            if (lsp != 0xFF)
                            {
                                data.resize(sizeof(nvme_lockdown_log));
                            }
                            else
                            {
                                data.resize(sizeof(nvme_lockdown_log) * 6);
                            }
                            std::fill(data.begin(), data.end(), 0);
                            break;
                        }

                        default:
                        {
                            lg2::error("unknown lid for GetLogPage");
                            throw std::system_error(std::make_error_code(
                                std::errc::invalid_argument));
                        }
                    }
                }
                catch (const ::std::system_error& e)
                {
                    boost::asio::post(
                        self->io,
                        [cb{cb}, ec = e.code()]() mutable { cb(ec, {}); });
                    return;
                }
                boost::asio::post(self->io,
                                  [cb{cb}, data{std::move(data)}]() mutable {
                    std::span<uint8_t> span{data.data(), data.size()};
                    cb({}, span);
                });
            });
        }
        catch (const std::runtime_error& e)
        {
            lg2::error("{ERROR}", "ERROR", e.what());
            boost::asio::post(io, [cb{std::move(cb)}]() {
                cb(std::make_error_code(std::errc::no_such_device), {});
            });
            return;
        }
    }
    void adminFwCommit(nvme_mi_ctrl_t /*ctrl*/, nvme_fw_commit_ca action,
                       uint8_t slot, bool bpid,
                       std::function<void(const std::error_code&,
                                          nvme_status_field)>&& cb) override
    {
        try
        {
            nvme_fw_commit_args args{};
            memset(&args, 0, sizeof(args));
            args.action = action;
            args.slot = slot;
            args.bpid = bpid;
            boost::asio::post(
                io, [cb{std::move(cb)}, self{shared_from_this()}]() mutable {
                // int rc = nvme_mi_admin_fw_commit(ctrl, &args);
                int rc = 1;
                if (rc < 0)
                {
                    lg2::error("fail to subsystem_health_status_poll: {ERROR}",
                               "ERROR", strerror(errno));
                    boost::asio::post(self->io, [cb{std::move(cb)}]() {
                        cb(std::make_error_code(static_cast<std::errc>(errno)),
                           nvme_status_field::NVME_SC_MASK);
                    });
                    return;
                }
                if (rc > 0)
                {
                    switch (rc & 0x7ff)
                    {
                        case NVME_SC_FW_NEEDS_CONV_RESET:
                        case NVME_SC_FW_NEEDS_SUBSYS_RESET:
                        case NVME_SC_FW_NEEDS_RESET:
                            boost::asio::post(self->io,
                                              [rc, cb{std::move(cb)}]() {
                                cb({}, static_cast<nvme_status_field>(rc));
                            });
                            break;
                        default:
                            std::string_view errMsg = statusToString(
                                static_cast<nvme_mi_resp_status>(rc));
                            lg2::error(
                                "fail to subsystem_health_status_poll: {ERROR}",
                                "ERROR", errMsg.data());
                            boost::asio::post(self->io,
                                              [rc, cb{std::move(cb)}]() {
                                cb(std::make_error_code(std::errc::bad_message),
                                   static_cast<nvme_status_field>(rc));
                            });
                    }
                    return;
                }
            });
        }
        catch (const std::runtime_error& e)
        {
            lg2::error("{ERROR}", "ERROR", e.what());
            boost::asio::post(io, [cb{std::move(cb)}]() {
                cb(std::make_error_code(std::errc::no_such_device),
                   nvme_status_field::NVME_SC_MASK);
            });
            return;
        }
    }

    void adminXfer(nvme_mi_ctrl_t /*ctrl*/,
                   const nvme_mi_admin_req_hdr& adminReq,
                   std::span<uint8_t> data, unsigned int /*timeout_ms*/,
                   std::function<void(const std::error_code&,
                                      const nvme_mi_admin_resp_hdr&,
                                      std::span<uint8_t>)>&& cb) override
    {
        try
        {
            std::vector<uint8_t> req(sizeof(nvme_mi_admin_req_hdr) +
                                     data.size());
            memcpy(req.data(), &adminReq, sizeof(nvme_mi_admin_req_hdr));
            memcpy(req.data() + sizeof(nvme_mi_admin_req_hdr), data.data(),
                   data.size());
            post([req{std::move(req)}, self{shared_from_this()},
                  cb{std::move(cb)}]() mutable {
                int rc = 0;

                nvme_mi_admin_req_hdr* reqHeader =
                    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                    reinterpret_cast<nvme_mi_admin_req_hdr*>(req.data());

                size_t respDataSize =
                    boost::endian::little_to_native<size_t>(reqHeader->dlen);
                // off_t respDataOffset =
                //     boost::endian::little_to_native<off_t>(reqHeader->doff);
                size_t bufSize = sizeof(nvme_mi_admin_resp_hdr) + respDataSize;
                std::vector<uint8_t> buf(bufSize);
                nvme_mi_admin_resp_hdr* respHeader =
                    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                    reinterpret_cast<nvme_mi_admin_resp_hdr*>(buf.data());
                (void)respHeader;
                // rc = nvme_mi_admin_xfer(
                //     ctrl, reqHeader, req.size() -
                //     sizeof(nvme_mi_admin_req_hdr), respHeader,
                //     respDataOffset, &respDataSize);

                if (rc < 0)
                {
                    lg2::error("failed to nvme_mi_admin_xfer");
                    boost::asio::post(self->io, [cb{std::move(cb)}]() {
                        cb(std::make_error_code(static_cast<std::errc>(errno)),
                           {}, {});
                    });
                    return;
                }
                // the MI interface will only consume protocol/io errors
                // The client will take the reponsibility to deal with nvme-mi
                // status flag and nvme status field(cwd3). cmd specific return
                // value (cdw0) is also client's job.

                buf.resize(sizeof(nvme_mi_admin_resp_hdr) + respDataSize);
                boost::asio::post(self->io, [cb{std::move(cb)},
                                             data{std::move(buf)}]() mutable {
                    std::span<uint8_t> span(data.begin() +
                                                sizeof(nvme_mi_admin_resp_hdr),
                                            data.end());
                    nvme_smart_log& log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        *reinterpret_cast<nvme_smart_log*>(span.data());
                    uint8_t temp = 40;
                    log.temperature[0] = temp;
                    log.temperature[1] = 1;
                    cb({},
                       // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                       *reinterpret_cast<nvme_mi_admin_resp_hdr*>(data.data()),
                       span);
                });
            });
        }
        catch (const std::runtime_error& e)
        {
            lg2::error("{ERROR}", "ERROR", e.what());
            boost::asio::post(io, [cb{std::move(cb)}]() {
                cb(std::make_error_code(std::errc::no_such_device), {}, {});
            });
            return;
        }
    }
    void adminLockdownInband(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl, [[maybe_unused]] uint8_t prohibit,
        [[maybe_unused]] const std::vector<uint8_t>& adminCmds,
        [[maybe_unused]] const std::vector<uint8_t>& features,
        [[maybe_unused]] const std::vector<uint8_t>& logPages,
        std::function<void(
            const std::error_code&, int nvmeStatus, uint32_t comptionDw0,
            const std::string& failureScope, uint32_t failureId)>&& cb) override
    {
        boost::asio::post(io, [cb = std::move(cb)]() mutable {
            cb(std::make_error_code(std::errc::not_supported), -1, 0, "", 0);
        });
    }
    void adminSecuritySend(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl, [[maybe_unused]] uint8_t proto,
        [[maybe_unused]] uint16_t protoSpecific,
        [[maybe_unused]] std::span<uint8_t> data,
        std::function<void(const std::error_code&, int nvmeStatus)>&& cb)
        override
    {
        cb(std::make_error_code(std::errc::not_supported), 0);
    }
    void adminSecurityReceive(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl, [[maybe_unused]] uint8_t proto,
        [[maybe_unused]] uint16_t protoSpecific,
        [[maybe_unused]] uint32_t transferLength,
        std::function<void(const std::error_code&, int nvmeStatus,
                           const std::span<uint8_t> data)>&& cb) override
    {
        cb(std::make_error_code(std::errc::not_supported), 0, {});
    }

    void adminFwDownload(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl,
        [[maybe_unused]] std::string firmwarefile,
        [[maybe_unused]] std::function<void(const std::error_code&,
                                            nvme_status_field)>&& cb) override
    {
        cb(std::make_error_code(std::errc::not_supported),
           nvme_status_field::NVME_SC_SUCCESS);
    }

    void adminNonDataCmd(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl, [[maybe_unused]] uint8_t opcode,
        [[maybe_unused]] uint32_t cdw1, [[maybe_unused]] uint32_t cdw2,
        [[maybe_unused]] uint32_t cdw3, [[maybe_unused]] uint32_t cdw10,
        [[maybe_unused]] uint32_t cdw11, [[maybe_unused]] uint32_t cdw12,
        [[maybe_unused]] uint32_t cdw13, [[maybe_unused]] uint32_t cdw14,
        [[maybe_unused]] uint32_t cdw15,
        [[maybe_unused]] std::function<void(
            const std::error_code&, int nvmeStatus, uint32_t comptionDw0)>&& cb)
        override
    {
        cb(std::make_error_code(std::errc::not_supported), 0, 0);
    }

    void createNamespace(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl, [[maybe_unused]] uint64_t size,
        [[maybe_unused]] size_t lbaFormat, [[maybe_unused]] bool metadataAtEnd,
        [[maybe_unused]] std::function<void(nvme_ex_ptr ex)>&& submittedCb,
        [[maybe_unused]] std::function<
            void(nvme_ex_ptr ex, NVMeNSIdentify newid)>&& finishedCb) override
    {
        /* TODO: return not support to the cb/s */
    }

    void adminDeleteNamespace(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl, [[maybe_unused]] uint32_t nsid,
        [[maybe_unused]] std::function<void(const std::error_code&,
                                            int nvmeStatus)>&& cb) override
    {
        cb(std::make_error_code(std::errc::not_supported), 0);
    }

    void adminListNamespaces(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl,
        [[maybe_unused]] std::function<
            void(nvme_ex_ptr ex, std::vector<uint32_t> ns)>&& cb) override
    {
        // return fake NS
        return cb({}, {1, 2});
    }

    void adminAttachDetachNamespace(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl, [[maybe_unused]] uint16_t ctrlid,
        [[maybe_unused]] uint32_t nsid, [[maybe_unused]] bool attach,
        [[maybe_unused]] std::function<void(const std::error_code&,
                                            int nvmeStatus)>&& cb) override
    {
        cb(std::make_error_code(std::errc::not_supported), 0);
    }

    void adminSanitize(
        [[maybe_unused]] nvme_mi_ctrl_t ctrl,
        [[maybe_unused]] enum nvme_sanitize_sanact sanact,
        [[maybe_unused]] uint8_t passes, [[maybe_unused]] uint32_t pattern,
        [[maybe_unused]] bool invertPattern,
        [[maybe_unused]] std::function<void(nvme_ex_ptr ex)>&& cb) override
    {
        /* TODO: return not support to the cb/s */
    }

  private:
    boost::asio::io_context& io;
    bool valid = false;

    bool workerStop = false;
    std::mutex workerMtx;
    std::condition_variable workerCv;
    boost::asio::io_context workerIO;
    bool workerIsNotified = false;
    std::thread thread;

    void post(std::function<void(void)>&& func);

    std::vector<nvme_mi_ctrl> ctrls;
};

inline void NVMeMiFake::post(std::function<void(void)>&& func)
{
    if (!workerStop)
    {
        std::unique_lock<std::mutex> lock(workerMtx);
        if (!workerStop)
        {
            lg2::info("do post");
            workerIsNotified = true;
            boost::asio::post(workerIO, std::move(func));
            workerCv.notify_all();
            return;
        }
    }
    throw std::runtime_error("NVMeMi has been stopped");
}
