/*
 * Copyright (c) 2021 Ampere Computing LLC
 *
 * Licensed 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.
 *
 * This is a daemon that forwards requests and receive responses from SSIF over
 * the D-Bus IPMI Interface.
 */

#include <getopt.h>
#include <linux/ipmi_bmc.h>

#include <CLI/CLI.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/asio.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/asio/sd_event.hpp>
#include <sdbusplus/timer.hpp>

#include <iostream>

/* Max length of ipmi ssif message included netfn and cmd field */
#define IPMI_SSIF_PAYLOAD_MAX 254

using namespace phosphor::logging;

struct ipmi_cmd
{
    uint8_t netfn;
    uint8_t lun;
    uint8_t cmd;
} prev_req_cmd;

static constexpr const char devBase[] = "/dev/ipmi-ssif-host";
/* SSIF use IPMI SSIF channel */
static constexpr const char* ssifBus =
    "xyz.openbmc_project.Ipmi.Channel.ipmi_ssif";
static constexpr const char* ssifObj =
    "/xyz/openbmc_project/Ipmi/Channel/ipmi_ssif";
/* The timer of driver is set to 15 seconds, need to send
 * response before timeout occurs
 */
static constexpr const unsigned int hostReqTimeout = 14000000;

class SsifChannel
{
  public:
    static constexpr size_t ssifMessageSize = IPMI_SSIF_PAYLOAD_MAX +
                                              sizeof(unsigned int);
    size_t sizeofLenField = sizeof(unsigned int);
    static constexpr uint8_t netFnShift = 2;
    static constexpr uint8_t lunMask = (1 << netFnShift) - 1;

    SsifChannel(std::shared_ptr<boost::asio::io_context>& io,
                std::shared_ptr<sdbusplus::asio::connection>& bus,
                const std::string& channel, bool verbose,
                int numberOfReqNotRsp);
    bool initOK() const
    {
        return !!dev;
    }
    void channelAbort(const char* msg, const boost::system::error_code& ec);
    void async_read();
    void processMessage(const boost::system::error_code& ecRd, size_t rlen);
    int showNumOfReqNotRsp();
    std::unique_ptr<boost::asio::posix::stream_descriptor> dev = nullptr;

  protected:
    std::array<uint8_t, ssifMessageSize> xferBuffer;
    std::shared_ptr<boost::asio::io_context> io;
    std::shared_ptr<sdbusplus::asio::connection> bus;
    std::shared_ptr<sdbusplus::asio::object_server> server;
    bool verbose;
    /* This variable is always 0 when a request is responsed properly,
     * any value larger than 0 meaning there is/are request(s) which
     * not processed properly
     * */
    int numberOfReqNotRsp;
};

std::unique_ptr<phosphor::Timer> rspTimer __attribute__((init_priority(101)));
std::unique_ptr<SsifChannel> ssifchannel = nullptr;

SsifChannel::SsifChannel(std::shared_ptr<boost::asio::io_context>& io,
                         std::shared_ptr<sdbusplus::asio::connection>& bus,
                         const std::string& device, bool verbose,
                         int numberOfReqNotRsp) :
    io(io),
    bus(bus), verbose(verbose), numberOfReqNotRsp(numberOfReqNotRsp)
{
    std::string devName = devBase;
    if (!device.empty())
    {
        devName = device;
    }

    // open device
    int fd = open(devName.c_str(), O_RDWR | O_NONBLOCK);
    if (fd < 0)
    {
        std::string msgToLog = "Couldn't open SSIF driver with flags O_RDWR."
                               " FILENAME=" +
                               devName + " ERROR=" + strerror(errno);
        log<level::ERR>(msgToLog.c_str());
        return;
    }
    else
    {
        dev = std::make_unique<boost::asio::posix::stream_descriptor>(*io, fd);
    }

    async_read();
    // register interfaces...
    server = std::make_shared<sdbusplus::asio::object_server>(bus);
    std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
        server->add_interface(ssifObj, ssifBus);
    iface->initialize();
}

void SsifChannel::channelAbort(const char* msg,
                               const boost::system::error_code& ec)
{
    std::string msgToLog = std::string(msg) + " ERROR=" + ec.message();
    log<level::ERR>(msgToLog.c_str());
    // bail; maybe a restart from systemd can clear the error
    io->stop();
}

void SsifChannel::async_read()
{
    boost::asio::async_read(*dev,
                            boost::asio::buffer(xferBuffer, xferBuffer.size()),
                            boost::asio::transfer_at_least(2),
                            [this](const boost::system::error_code& ec,
                                   size_t rlen) { processMessage(ec, rlen); });
}

int SsifChannel::showNumOfReqNotRsp()
{
    return numberOfReqNotRsp;
}

void rspTimerHandler()
{
    std::vector<uint8_t> rsp;
    constexpr uint8_t ccResponseNotAvailable = 0xce;

    rsp.resize(ssifchannel->sizeofLenField + sizeof(prev_req_cmd.cmd) +
               sizeof(prev_req_cmd.netfn) + sizeof(ccResponseNotAvailable));
    std::string msgToLog = "timeout, send response to keep host alive"
                           " netfn=" +
                           std::to_string(prev_req_cmd.netfn) +
                           " lun=" + std::to_string(prev_req_cmd.lun) +
                           " cmd=" + std::to_string(prev_req_cmd.cmd) +
                           " cc=" + std::to_string(ccResponseNotAvailable) +
                           " numberOfReqNotRsp=" +
                           std::to_string(ssifchannel->showNumOfReqNotRsp());
    log<level::INFO>(msgToLog.c_str());

    unsigned int* t = (unsigned int*)&rsp[0];
    *t = 3;
    rsp[ssifchannel->sizeofLenField] =
        ((prev_req_cmd.netfn + 1) << ssifchannel->netFnShift) |
        (prev_req_cmd.lun & ssifchannel->lunMask);
    rsp[ssifchannel->sizeofLenField + 1] = prev_req_cmd.cmd;
    rsp[ssifchannel->sizeofLenField + 2] = ccResponseNotAvailable;

    boost::system::error_code ecWr;

    size_t wlen = boost::asio::write(*(ssifchannel->dev),
                                     boost::asio::buffer(rsp), ecWr);
    if (ecWr || wlen != rsp.size())
    {
        msgToLog =
            "Failed to send ssif respond message:"
            " size=" +
            std::to_string(wlen) + " expect=" + std::to_string(rsp.size()) +
            " error=" + ecWr.message() +
            " netfn=" + std::to_string(prev_req_cmd.netfn + 1) +
            " lun=" + std::to_string(prev_req_cmd.lun) +
            " cmd=" + std::to_string(rsp[ssifchannel->sizeofLenField + 1]) +
            " cc=" + std::to_string(ccResponseNotAvailable);
        log<level::ERR>(msgToLog.c_str());
    }
}

void initTimer()
{
    if (!rspTimer)
    {
        rspTimer = std::make_unique<phosphor::Timer>(rspTimerHandler);
    }
}

void SsifChannel::processMessage(const boost::system::error_code& ecRd,
                                 size_t rlen)
{
    if (ecRd || rlen < 2)
    {
        channelAbort("Failed to read req msg", ecRd);
        return;
    }
    async_read();

    auto rawIter = xferBuffer.cbegin();
    auto rawEnd = rawIter + rlen;
    uint8_t netfn = rawIter[sizeofLenField] >> netFnShift;
    uint8_t lun = rawIter[sizeofLenField] & lunMask;
    uint8_t cmd = rawIter[sizeofLenField + 1];

    /* keep track of previous request */
    prev_req_cmd.netfn = netfn;
    prev_req_cmd.lun = lun;
    prev_req_cmd.cmd = cmd;

    /* there is a request coming */
    numberOfReqNotRsp++;
    /* start response timer */
    rspTimer->start(std::chrono::microseconds(hostReqTimeout), false);

    if (verbose)
    {
        unsigned int lenRecv;
        unsigned int* p = (unsigned int*)rawIter;
        lenRecv = p[0];
        std::string msgToLog =
            "Read ssif request message with"
            " len=" +
            std::to_string(lenRecv) + " netfn=" + std::to_string(netfn) +
            " lun=" + std::to_string(lun) + " cmd=" + std::to_string(cmd) +
            " numberOfReqNotRsp=" + std::to_string(numberOfReqNotRsp);
        log<level::INFO>(msgToLog.c_str());
    }
    // copy out payload
    std::vector<uint8_t> data(rawIter + sizeofLenField + 2, rawEnd);
    // non-session bridges still need to pass an empty options map
    std::map<std::string, std::variant<int>> options;
    // the response is a tuple because dbus can only return a single value
    using IpmiDbusRspType =
        std::tuple<uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>;
    static constexpr const char ipmiQueueService[] =
        "xyz.openbmc_project.Ipmi.Host";
    static constexpr const char ipmiQueuePath[] = "/xyz/openbmc_project/Ipmi";
    static constexpr const char ipmiQueueIntf[] =
        "xyz.openbmc_project.Ipmi.Server";
    static constexpr const char ipmiQueueMethod[] = "execute";
    /* now, we do not care dbus timeout, since we already have actions
     * before dbus timeout occurs
     */
    static constexpr unsigned int dbusTimeout = 60000000;
    bus->async_method_call_timed(
        [this, netfnCap{netfn}, lunCap{lun},
         cmdCap{cmd}](const boost::system::error_code& ec,
                      const IpmiDbusRspType& response) {
        std::vector<uint8_t> rsp;
        const auto& [netfn, lun, cmd, cc, payload] = response;
        numberOfReqNotRsp--;
        if (ec)
        {
            std::string msgToLog =
                "ssif<->ipmid bus error:"
                " netfn=" +
                std::to_string(netfn) + " lun=" + std::to_string(lun) +
                " cmd=" + std::to_string(cmd) + " error=" + ec.message();
            log<level::ERR>(msgToLog.c_str());
            rsp.resize(sizeofLenField + sizeof(netfn) + sizeof(cmd) +
                       sizeof(cc));
            /* if dbusTimeout, just return and do not send any response
             * to let host continue with other commands, response here
             * is potentially make the response duplicated
             * */
            return;
        }
        else
        {
            if ((prev_req_cmd.netfn != (netfn - 1) || prev_req_cmd.lun != lun ||
                 prev_req_cmd.cmd != cmd) ||
                ((prev_req_cmd.netfn == (netfn - 1) &&
                  prev_req_cmd.lun == lun && prev_req_cmd.cmd == cmd) &&
                 numberOfReqNotRsp != 0))
            {
                /* Only send response to the last request command to void
                 * duplicated response which makes host driver confused and
                 * failed to create interface
                 *
                 * Drop responses which are (1) different from the request
                 * (2) parameters are the same as request but handshake flow
                 * are in dupplicate request state
                 * */
                if (verbose)
                {
                    std::string msgToLog = "Drop ssif respond message with"
                                           " len=" +
                                           std::to_string(payload.size() + 3) +
                                           " netfn=" + std::to_string(netfn) +
                                           " lun=" + std::to_string(lun) +
                                           " cmd=" + std::to_string(cmd) +
                                           " cc=" + std::to_string(cc) +
                                           " numberOfReqNotRsp=" +
                                           std::to_string(numberOfReqNotRsp);
                    log<level::INFO>(msgToLog.c_str());
                }
                return;
            }
            rsp.resize(sizeofLenField + sizeof(netfn) + sizeof(cmd) +
                       sizeof(cc) + payload.size());

            // write the response
            auto rspIter = rsp.begin();
            unsigned int* p = (unsigned int*)&rspIter[0];
            *p = payload.size() + 3;
            rspIter[sizeofLenField] = (netfn << netFnShift) | (lun & lunMask);
            rspIter[sizeofLenField + 1] = cmd;
            rspIter[sizeofLenField + 2] = cc;
            if (payload.size())
            {
                std::copy(payload.cbegin(), payload.cend(),
                          rspIter + sizeofLenField + 3);
            }
        }
        if (verbose)
        {
            std::string msgToLog =
                "Send ssif respond message with"
                " len=" +
                std::to_string(payload.size() + 3) +
                " netfn=" + std::to_string(netfn) +
                " lun=" + std::to_string(lun) + " cmd=" + std::to_string(cmd) +
                " cc=" + std::to_string(cc) +
                " numberOfReqNotRsp=" + std::to_string(numberOfReqNotRsp);
            log<level::INFO>(msgToLog.c_str());
        }
        boost::system::error_code ecWr;
        size_t wlen = boost::asio::write(*dev, boost::asio::buffer(rsp), ecWr);
        if (ecWr || wlen != rsp.size())
        {
            std::string msgToLog =
                "Failed to send ssif respond message:"
                " size=" +
                std::to_string(wlen) + " expect=" + std::to_string(rsp.size()) +
                " error=" + ecWr.message() + " netfn=" + std::to_string(netfn) +
                " lun=" + std::to_string(lun) + " cmd=" + std::to_string(cmd) +
                " cc=" + std::to_string(cc);
            log<level::ERR>(msgToLog.c_str());
        }
        rspTimer->stop();
    },
        ipmiQueueService, ipmiQueuePath, ipmiQueueIntf, ipmiQueueMethod,
        dbusTimeout, netfn, lun, cmd, data, options);
}

int main(int argc, char* argv[])
{
    CLI::App app("SSIF IPMI bridge");
    std::string device;
    app.add_option("-d,--device", device,
                   "use <DEVICE> file. Default is /dev/ipmi-ssif-host");
    bool verbose = false;
    int numberOfReqNotRsp = 0;
    app.add_option("-v,--verbose", verbose, "print more verbose output");
    CLI11_PARSE(app, argc, argv);

    // Connect to system bus
    auto io = std::make_shared<boost::asio::io_context>();
    sd_bus* dbus;
    sd_bus_default_system(&dbus);

    /* This might be a phosphor::Timer bug, without timer t2, rspTimer
     * will not work
     */
    phosphor::Timer t2([]() { ; });
    t2.start(std::chrono::microseconds(500000), true);
    auto bus = std::make_shared<sdbusplus::asio::connection>(*io, dbus);
    bus->request_name(ssifBus);
    // Create the SSIF channel, listening on D-Bus and on the SSIF device
    ssifchannel = make_unique<SsifChannel>(io, bus, device, verbose,
                                           numberOfReqNotRsp);
    if (!ssifchannel->initOK())
    {
        return EXIT_FAILURE;
    }
    initTimer();
    sdbusplus::asio::sd_event_wrapper sdEvents(*io);
    io->run();

    return 0;
}
