/*
 * Copyright 2018 Google Inc.
 *
 * 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.
 */

#include "i2c.hpp"

#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <array>
#include <cerrno>
#include <cstring>
#include <ipmid/iana.hpp>
#include <ipmid/oemopenbmc.hpp>
#include <memory>

namespace oem
{
namespace i2c
{

// Instance object.
std::unique_ptr<I2c> globalOemI2c;

// Block read (I2C_M_RECV_LEN) reads count byte, then that many bytes,
// then possibly a checksum byte. The specified byte count limit,
// I2C_SMBUS_BLOCK_MAX, is 32, but it seems intractible to prove
// every I2C implementation uses that limit. So to prevent overflow,
// allocate buffers based on the largest possible count byte of 255.
constexpr size_t maxRecvLenBuf = 1 + 255 + 1;
typedef std::array<uint8_t, maxRecvLenBuf> BlockBuf;

struct ParsedStep
{
    const uint8_t* reqData;
    size_t length;
    DevAddr devAddr;
    bool isRead;
    // When nonzero, device supplies count for this step, as in SMBUS block
    // mode. Value will tell driver how many extra bytes to read for entire
    // block: 1 for count byte w/o PEC, 2 if there is also a PEC byte.
    uint16_t blockExtra;
    bool noStart;
};

struct ParsedReq
{
    BusId localbus;
    bool usePec;
    size_t numSteps;
    std::array<ParsedStep, maxSteps> step;
};

static ipmi_ret_t parseReqHdr(const uint8_t* reqBuf, size_t reqLen,
                              size_t* bytesUsed, i2c::ParsedReq* req)
{
    // Request header selects bus & flags for operation;
    // additional bytes beyond are to be interpreted as steps.
    if (reqLen < *bytesUsed + requestHeaderLen)
    {
        std::fprintf(stderr, "i2c::parse reqLen=%zu?\n", reqLen);
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }
    // Deserialize request header bytes.
    req->localbus = reqBuf[requestHeaderBus];
    auto reqFlags = reqBuf[requestHeaderFlags];
    *bytesUsed += requestHeaderLen;

    // Decode flags.
    req->usePec = !!(reqFlags & requestFlagsUsePec);
    return IPMI_CC_OK;
}

static ipmi_ret_t parseReqStep(const uint8_t* reqBuf, size_t reqLen,
                               size_t* bytesUsed, i2c::ParsedReq* req)
{
    size_t bytesLeft = reqLen - *bytesUsed;
    if (req->numSteps >= maxSteps || bytesLeft < stepHeaderLen)
    {
        std::fprintf(stderr, "i2c::parse[%zu] bytesLeft=%zu?\n", req->numSteps,
                     bytesLeft);
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }
    const uint8_t* stepHdr = reqBuf + *bytesUsed;
    auto step = &req->step[req->numSteps++];

    // Deserialize request step header bytes.
    uint8_t devAndDir = stepHdr[stepHeaderDevAndDir];
    uint8_t stepFlags = stepHdr[stepHeaderFlags];
    step->length = stepHdr[stepHeaderParm];
    bytesLeft -= stepHeaderLen;
    *bytesUsed += stepHeaderLen;

    // Decode device addr & direction.
    step->devAddr = devAndDir >> 1;
    step->isRead = !!(devAndDir & 1);

    // Decode step flags.
    step->noStart = !!(stepFlags & stepFlagsNoStart);

    if (step->isRead)
    {
        // Read could select blockExtra.
        if (stepFlags & stepFlagsRecvLen)
        {
            step->blockExtra = req->usePec ? 2 : 1;
        }
    }
    else
    {
        // For write, requested byte count must follow.
        if (bytesLeft < step->length)
        {
            std::fprintf(stderr, "i2c::parse[%zu] bytesLeft=%zu, parm=%zu?\n",
                         req->numSteps, bytesLeft, step->length);
            return IPMI_CC_REQ_DATA_LEN_INVALID;
        }
        step->reqData = reqBuf + *bytesUsed;
        *bytesUsed += step->length;
    }
    return IPMI_CC_OK;
}

// Parse i2c request.
static ipmi_ret_t parse(const uint8_t* reqBuf, size_t reqLen,
                        i2c::ParsedReq* req)
{
    size_t bytesUsed = 0;
    auto rc = parseReqHdr(reqBuf, reqLen, &bytesUsed, req);
    if (rc != IPMI_CC_OK)
    {
        return rc;
    }
    do
    {
        rc = parseReqStep(reqBuf, reqLen, &bytesUsed, req);
        if (rc != IPMI_CC_OK)
        {
            return rc;
        }
    } while (bytesUsed < reqLen);
    return IPMI_CC_OK;
}

// Convert parsed request to I2C messages.
static ipmi_ret_t buildI2cMsgs(const i2c::ParsedReq& req,
                               std::unique_ptr<i2c::BlockBuf> rxBuf[],
                               struct i2c_msg msgs[],
                               struct i2c_rdwr_ioctl_data* msgset)
{
    size_t minReplyLen = 0;

    for (size_t i = 0; i < req.numSteps; ++msgset->nmsgs, ++i)
    {
        const auto& step = req.step[i];
        auto* msg = &msgs[i];
        msg->addr = step.devAddr;

        if (!step.isRead)
        {
            msg->flags = 0;
            msg->len = step.length;
            msg->buf = const_cast<uint8_t*>(step.reqData);
            continue;
        }
        rxBuf[i] = std::make_unique<i2c::BlockBuf>();
        msg->buf = rxBuf[i]->data();

        if (step.blockExtra == 0)
        {
            msg->flags = I2C_M_RD;
            msg->len = step.length;
            minReplyLen += msg->len;
        }
        else
        {
            // Special buffer setup needed for block read:
            // . 1. msg len must allow for maximum possible transfer,
            // . 2. blockExtra must be preloaded into buf[0]
            // The internal i2c_transfer API is slightly different;
            // the rdwr ioctl handler adapts by moving blockExtra
            // into msg.len where the driver will expect to find it.
            //
            // References:
            //  drivers/i2c/i2c-dev.c: i2cdev_ioctl_rdwr()
            msg->flags = I2C_M_RD | I2C_M_RECV_LEN;
            msg->len = maxRecvLenBuf;
            msg->buf[0] = step.blockExtra;
            minReplyLen += step.blockExtra;
        }
    }

    if (minReplyLen > i2c::largestReply)
    {
        std::fprintf(stderr, "I2c::transfer minReplyLen=%zu?\n", minReplyLen);
        return IPMI_CC_RESPONSE_ERROR; // Won't fit in response message
    }

#ifdef __IPMI_DEBUG__
    for (size_t i = 0; i < req.numSteps; ++i)
    {
        auto* msg = &msgs[i];
        std::fprintf(stderr, "I2c::transfer msg[%zu]: %02x %04x %d\n", i,
                     msg->addr, msg->flags, msg->len);
    }
#endif

    return IPMI_CC_OK;
}

static int openBus(BusId localbus)
{
    char busCharDev[16];
    std::snprintf(busCharDev, sizeof(busCharDev) - 1, "/dev/i2c-%d", localbus);
    int busFd = open(busCharDev, O_RDWR);
    if (busFd < 0)
    {
        std::fprintf(stderr,
                     "NetFn:[0x2E], OEM:[0x002B79], Cmd:[0x02], "
                     "I2C Bus Open(\"%s\"): \"%s\"\n",
                     busCharDev, strerror(-busFd));
    }
    return busFd;
}

} // namespace i2c

ipmi_ret_t I2c::transfer(ipmi_cmd_t cmd, const uint8_t* reqBuf,
                         uint8_t* replyBuf, size_t* dataLen)
{
    // Parse message header.
    auto reqLen = *dataLen;
    *dataLen = 0;
    i2c::ParsedReq req = {};
    auto rc = parse(reqBuf, reqLen, &req);
    if (rc != IPMI_CC_OK)
    {
        return rc;
    }

    // Build full msgset
    std::unique_ptr<i2c::BlockBuf> rxBuf[i2c::maxSteps];
    struct i2c_msg msgs[i2c::maxSteps] = {};
    struct i2c_rdwr_ioctl_data msgset = {
        .msgs = msgs,
        .nmsgs = 0,
    };
    rc = buildI2cMsgs(req, rxBuf, msgs, &msgset);
    if (rc != IPMI_CC_OK)
    {
        return rc;
    }

    // Try to open i2c bus
    int busFd = i2c::openBus(req.localbus);
    if (busFd < 0)
    {
        return IPMI_CC_UNSPECIFIED_ERROR;
    }
    int ioError = ioctl(busFd, I2C_RDWR, &msgset);

    // Done with busFd, so close it immediately to avoid leaking it.
    (void)close(busFd);
    if (ioError < 0)
    {
        std::fprintf(stderr, "I2c::transfer I2C_RDWR ioError=%d?\n", ioError);
        return IPMI_CC_UNSPECIFIED_ERROR; // I2C_RDWR I/O error
    }

    // If we read any data, append it, in the order we read it.
    uint8_t* nextReplyByte = replyBuf;
    size_t replyLen = 0;
    for (size_t i = 0; i < req.numSteps; ++i)
    {
        const auto& step = req.step[i];
        if (step.isRead)
        {
            const auto* msg = &msgs[i];
            size_t lenRead =
                step.blockExtra ? *msg->buf + step.blockExtra : msg->len;
            replyLen += lenRead;
            if (replyLen > i2c::largestReply)
            {
                std::fprintf(stderr, "I2c::transfer[%zu] replyLen=%zu?\n", i,
                             replyLen);
                return IPMI_CC_RESPONSE_ERROR; // Won't fit in response message
            }
            std::memcpy(nextReplyByte, msg->buf, lenRead);
            nextReplyByte += lenRead;
        }
    }
    *dataLen = replyLen;
    return IPMI_CC_OK;
}

void I2c::registerWith(Router* oemRouter)
{
    Handler f = [this](ipmi_cmd_t cmd, const uint8_t* reqBuf, uint8_t* replyBuf,
                       size_t* dataLen) {
        return transfer(cmd, reqBuf, replyBuf, dataLen);
    };

    std::fprintf(stderr, "Registering OEM:[%#08X], Cmd:[%#04X] for I2C\n",
                 googOemNumber, Cmd::i2cCmd);
    oemRouter->registerHandler(googOemNumber, Cmd::i2cCmd, f);

    std::fprintf(stderr, "Registering OEM:[%#08X], Cmd:[%#04X] for I2C\n",
                 obmcOemNumber, Cmd::i2cCmd);
    oemRouter->registerHandler(obmcOemNumber, Cmd::i2cCmd, f);
}

namespace i2c
{
// Currently ipmid dynamically loads providers such as these;
// this creates our singleton upon load.
void setupGlobalOemI2c() __attribute__((constructor));

void setupGlobalOemI2c()
{
    globalOemI2c = std::make_unique<I2c>();
    globalOemI2c->registerWith(oem::mutableRouter());
}
} // namespace i2c
} // namespace oem
