#include "config.h"

#include "dump_offload.hpp"

#include <fmt/core.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#include <dump_utils.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <xyz/openbmc_project/Common/File/error.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

#include <fstream>

namespace phosphor
{
namespace dump
{
namespace offload
{

using namespace sdbusplus::xyz::openbmc_project::Common::Error;
using namespace phosphor::logging;

/** @brief API to write data on unix socket.
 *
 * @param[in] socket     - unix socket
 * @param[in] buf        - buffer
 * @param[in] blockSize  - size of data
 *
 * @return  void
 */
void writeOnUnixSocket(const int socket, const char* buf,
                       const uint64_t blockSize)
{
    int numOfBytesWrote = 0;

    for (uint64_t i = 0; i < blockSize; i = i + numOfBytesWrote)
    {
        numOfBytesWrote = 0;
        fd_set writeFileDescriptor;
        struct timeval timeVal;
        timeVal.tv_sec = 5;
        timeVal.tv_usec = 0;

        FD_ZERO(&writeFileDescriptor);
        FD_SET(socket, &writeFileDescriptor);
        int nextFileDescriptor = socket + 1;

        int retVal = select(nextFileDescriptor, NULL, &writeFileDescriptor,
                            NULL, &timeVal);
        if (retVal <= 0)
        {
            log<level::ERR>(
                fmt::format("writeOnUnixSocket: select() failed, errno({})",
                            errno)
                    .c_str());
            std::string msg = "select() failed " + std::string(strerror(errno));
            throw std::runtime_error(msg);
        }
        if ((retVal > 0) && (FD_ISSET(socket, &writeFileDescriptor)))
        {
            numOfBytesWrote = write(socket, buf + i, blockSize - i);
            if (numOfBytesWrote < 0)
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
                {
                    numOfBytesWrote = 0;
                    continue;
                }
                log<level::ERR>(
                    fmt::format("writeOnUnixSocket: write() failed, errno({})",
                                errno)
                        .c_str());
                std::string msg = "write() on socket failed " +
                                  std::string(strerror(errno));
                throw std::runtime_error(msg);
            }
        }
    }
    return;
}

/**@brief API to setup unix socket.
 *
 * @param[in] sockPath  - unix socket path
 *
 * @return returns returns socket fd on success
 *                 and on error exception will be thrown
 */
int socketInit(const std::string& sockPath)
{
    int unixSocket;
    struct sockaddr_un socketAddr;
    memset(&socketAddr, 0, sizeof(socketAddr));
    socketAddr.sun_family = AF_UNIX;
    if (strnlen(sockPath.c_str(), sizeof(socketAddr.sun_path)) ==
        sizeof(socketAddr.sun_path))
    {
        log<level::ERR>("UNIX socket path too long");
        std::string msg = "UNIX socket path is too long " +
                          std::string(strerror(errno));
        throw std::length_error(msg);
    }
    strncpy(socketAddr.sun_path, sockPath.c_str(),
            sizeof(socketAddr.sun_path) - 1);
    if ((unixSocket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1)
    {
        log<level::ERR>(
            fmt::format("socketInit: socket() failed, errno({})", errno)
                .c_str());
        std::string msg = "socket() failed " + std::string(strerror(errno));
        throw std::runtime_error(msg);
    }
    if (bind(unixSocket, (struct sockaddr*)&socketAddr, sizeof(socketAddr)) ==
        -1)
    {
        log<level::ERR>(
            fmt::format("socketInit: bind() failed, errno({})", errno).c_str());
        close(unixSocket);
        std::string msg = "socket bind failed " + std::string(strerror(errno));
        throw std::runtime_error(msg);
    }
    if (listen(unixSocket, 1) == -1)
    {
        log<level::ERR>(
            fmt::format("socketInit: listen() failed, errno({})", errno)
                .c_str());
        close(unixSocket);
        std::string msg = "listen() failed " + std::string(strerror(errno));
        throw std::runtime_error(msg);
    }
    return unixSocket;
}

void requestOffload(std::filesystem::path file, uint32_t dumpId,
                    std::string writePath)
{
    using namespace sdbusplus::xyz::openbmc_project::Common::File::Error;
    using ErrnoOpen = xyz::openbmc_project::Common::File::Open::ERRNO;
    using PathOpen = xyz::openbmc_project::Common::File::Open::PATH;
    using ErrnoWrite = xyz::openbmc_project::Common::File::Write::ERRNO;
    using PathWrite = xyz::openbmc_project::Common::File::Write::PATH;

    try
    {
        CustomFd unixSocket = socketInit(writePath);

        fd_set readFD;
        struct timeval timeVal;
        timeVal.tv_sec = 1;
        timeVal.tv_usec = 0;

        FD_ZERO(&readFD);
        FD_SET(unixSocket(), &readFD);
        int numOfFDs = unixSocket() + 1;

        int retVal = select(numOfFDs, &readFD, NULL, NULL, &timeVal);
        if (retVal <= 0)
        {
            log<level::ERR>(
                fmt::format("select() failed, errno({}), DUMP_ID({})", errno,
                            dumpId)
                    .c_str());
            std::string msg = "select() failed " + std::string(strerror(errno));
            throw std::runtime_error(msg);
        }
        else if ((retVal > 0) && (FD_ISSET(unixSocket(), &readFD)))
        {
            CustomFd socketFD = accept(unixSocket(), NULL, NULL);
            if (socketFD() < 0)
            {
                log<level::ERR>(
                    fmt::format("accept() failed, errno({}), DUMP_ID({})",
                                errno, dumpId)
                        .c_str());
                std::string msg = "accept() failed " +
                                  std::string(strerror(errno));
                throw std::runtime_error(msg);
            }

            std::ifstream infile{file, std::ios::in | std::ios::binary};
            if (!infile.good())
            {
                // Unable to open the dump file
                log<level::ERR>(
                    fmt::format("Failed to open the dump from file, errno({}), "
                                "DUMPFILE({}), DUMP_ID({})",
                                errno, file.c_str(), dumpId)
                        .c_str());
                elog<Open>(ErrnoOpen(errno), PathOpen(file.c_str()));
            }

            infile.exceptions(std::ifstream::failbit | std::ifstream::badbit |
                              std::ifstream::eofbit);

            log<level::INFO>(fmt::format("Opening File for RW, FILENAME({})",
                                         file.filename().c_str())
                                 .c_str());

            std::filebuf* pbuf = infile.rdbuf();

            // get file size using buffer's members
            std::size_t size = pbuf->pubseekoff(0, infile.end, infile.in);
            pbuf->pubseekpos(0, infile.in);

            // allocate memory to contain file data
            std::unique_ptr<char[]> buffer(new char[size]);
            // get file data
            pbuf->sgetn(buffer.get(), size);
            infile.close();

            writeOnUnixSocket(socketFD(), buffer.get(), size);
        }
    }
    catch (const std::ifstream::failure& oe)
    {
        std::remove(writePath.c_str());
        auto err = errno;
        log<level::ERR>(
            fmt::format(
                "Failed to open, errormsg({}), OPENINTERFACE({}), DUMP_ID({})",
                oe.what(), file.c_str(), dumpId)
                .c_str());
        elog<Open>(ErrnoOpen(err), PathOpen(file.c_str()));
    }
    catch (const std::exception& e)
    {
        std::remove(writePath.c_str());
        auto err = errno;
        log<level::ERR>(fmt::format("Failed to offload dump, errormsg({}), "
                                    "DUMPFILE({}), DUMP_ID({})",
                                    e.what(), writePath.c_str(), dumpId)
                            .c_str());
        elog<Write>(ErrnoWrite(err), PathWrite(writePath.c_str()));
    }
    std::remove(writePath.c_str());
    return;
}

} // namespace offload
} // namespace dump
} // namespace phosphor
