#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:
                        {
                            data.resize(sizeof(nvme_lockdown_log));
                            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");
}
