/*
 * 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 "ipmi_handler.hpp"

#include "ipmi_errors.hpp"

#include <fcntl.h>
#include <linux/ipmi.h>
#include <linux/ipmi_msgdefs.h>
#include <sys/ioctl.h>

#include <array>
#include <cstdint>
#include <cstring>
#include <sstream>
#include <string>
#include <vector>

namespace host_tool
{

void IpmiHandler::open()
{
    const int device = 0;
    const std::vector<std::string> formats = {"/dev/ipmi", "/dev/ipmi/",
                                              "/dev/ipmidev/"};

    for (const auto& format : formats)
    {
        std::ostringstream path;
        path << format << device;

        fd = sys->open(path.str().c_str(), O_RDWR);
        if (fd < 0)
        {
            continue;
        }
        break;
    }

    if (fd < 0)
    {
        throw IpmiException("Unable to open any ipmi devices");
    }
}

std::vector<std::uint8_t>
    IpmiHandler::sendPacket(std::vector<std::uint8_t>& data)
{
    if (fd < 0)
    {
        open();
    }

    constexpr int ipmiOEMNetFn = 46;
    constexpr int ipmiOEMLun = 0;
    /* /openbmc/phosphor-host-ipmid/blob/master/host-ipmid/oemopenbmc.hpp */
    constexpr int ipmiOEMBlobCmd = 128;
    constexpr int fifteenMs = 15 * 1000;
    constexpr int ipmiReadTimeout = fifteenMs;
    constexpr int ipmiResponseBufferLen = IPMI_MAX_MSG_LENGTH;
    constexpr int ipmiOk = 0;

    /* We have a handle to the IPMI device. */
    std::array<std::uint8_t, ipmiResponseBufferLen> responseBuffer;

    /* Build address. */
    struct ipmi_system_interface_addr systemAddress;
    systemAddress.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
    systemAddress.channel = IPMI_BMC_CHANNEL;
    systemAddress.lun = ipmiOEMLun;

    /* Build request. */
    struct ipmi_req request;
    std::memset(&request, 0, sizeof(request));
    request.addr = reinterpret_cast<unsigned char*>(&systemAddress);
    request.addr_len = sizeof(systemAddress);
    request.msgid = sequence++;
    request.msg.data = reinterpret_cast<unsigned char*>(data.data());
    request.msg.data_len = data.size();
    request.msg.netfn = ipmiOEMNetFn;
    request.msg.cmd = ipmiOEMBlobCmd;

    struct ipmi_recv reply;
    reply.addr = reinterpret_cast<unsigned char*>(&systemAddress);
    reply.addr_len = sizeof(systemAddress);
    reply.msg.data = reinterpret_cast<unsigned char*>(responseBuffer.data());
    reply.msg.data_len = responseBuffer.size();

    /* Try to send request. */
    int rc = sys->ioctl(fd, IPMICTL_SEND_COMMAND, &request);
    if (rc < 0)
    {
        throw IpmiException("Unable to send IPMI request.");
    }

    /* Could use sdeventplus, but for only one type of event is it worth it? */
    struct pollfd pfd;
    pfd.fd = fd;
    pfd.events = POLLIN;

    do
    {
        rc = sys->poll(&pfd, 1, ipmiReadTimeout);
        if (rc < 0)
        {
            if (errno == EINTR)
            {
                continue;
            }
            throw IpmiException("Error occurred.");
        }
        else if (rc == 0)
        {
            throw IpmiException("Timeout waiting for reply.");
        }

        /* Yay, happy case! */
        rc = sys->ioctl(fd, IPMICTL_RECEIVE_MSG_TRUNC, &reply);
        if (rc < 0)
        {
            throw IpmiException("Unable to read reply.");
        }

        if (request.msgid != reply.msgid)
        {
            std::fprintf(stderr, "Received wrong message, trying again.\n");
        }
    } while (request.msgid != reply.msgid);

    if (responseBuffer[0] != ipmiOk)
    {
        throw IpmiException(static_cast<int>(responseBuffer[0]));
    }

    std::vector<std::uint8_t> returning;
    auto dataLen = reply.msg.data_len - 1;

    returning.insert(returning.begin(), responseBuffer.begin() + 1,
                     responseBuffer.begin() + dataLen + 1);

    for (const auto& byte : returning)
    {
        std::fprintf(stderr, "0x%02x ", byte);
    }
    std::fprintf(stderr, "\n");

    return returning;
}

} // namespace host_tool
