#include "mock_syscall.hpp"

#include "util.hpp"

#include <arpa/inet.h>
#include <dlfcn.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#include <cstdarg>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <stdexcept>
#include <stdplus/raw.hpp>
#include <string>
#include <string_view>
#include <vector>

std::map<int, std::queue<std::string>> mock_rtnetlinks;

using phosphor::network::system::InterfaceInfo;

std::map<std::string, InterfaceInfo> mock_if;

void phosphor::network::system::mock_clear()
{
    mock_rtnetlinks.clear();
    mock_if.clear();
}

void phosphor::network::system::mock_addIF(const InterfaceInfo& info)
{
    if (info.idx == 0)
    {
        throw std::invalid_argument("Bad interface index");
    }
    for (const auto& [_, iinfo] : mock_if)
    {
        if (iinfo.idx == info.idx || iinfo.name == info.name)
        {
            throw std::invalid_argument("Interface already exists");
        }
    }
    mock_if.emplace(info.name.value(), info);
}

void validateMsgHdr(const struct msghdr* msg)
{
    if (msg->msg_namelen != sizeof(sockaddr_nl))
    {
        fprintf(stderr, "bad namelen: %u\n", msg->msg_namelen);
        abort();
    }
    const auto& from = *reinterpret_cast<sockaddr_nl*>(msg->msg_name);
    if (from.nl_family != AF_NETLINK)
    {
        fprintf(stderr, "recvmsg bad family data\n");
        abort();
    }
    if (msg->msg_iovlen != 1)
    {
        fprintf(stderr, "recvmsg unsupported iov configuration\n");
        abort();
    }
}

void appendRTAttr(std::string& msgBuf, unsigned short type,
                  std::string_view data)
{
    const auto rta_begin = msgBuf.size();
    msgBuf.append(RTA_SPACE(data.size()), '\0');
    auto& rta = *reinterpret_cast<rtattr*>(msgBuf.data() + rta_begin);
    rta.rta_len = RTA_LENGTH(data.size());
    rta.rta_type = type;
    std::copy(data.begin(), data.end(),
              msgBuf.data() + rta_begin + RTA_LENGTH(0));
}

ssize_t sendmsg_link_dump(std::queue<std::string>& msgs, std::string_view in)
{
    if (const auto& hdrin = *reinterpret_cast<const nlmsghdr*>(in.data());
        hdrin.nlmsg_type != RTM_GETLINK)
    {
        return 0;
    }

    std::string msgBuf;
    msgBuf.reserve(8192);
    for (const auto& [name, i] : mock_if)
    {
        if (msgBuf.size() > 4096)
        {
            msgs.emplace(std::move(msgBuf));
        }
        const auto nlbegin = msgBuf.size();
        msgBuf.append(NLMSG_SPACE(sizeof(ifinfomsg)), '\0');
        {
            auto& info = *reinterpret_cast<ifinfomsg*>(msgBuf.data() + nlbegin +
                                                       NLMSG_HDRLEN);
            info.ifi_index = i.idx;
            info.ifi_flags = i.flags;
        }
        if (i.name)
        {
            appendRTAttr(msgBuf, IFLA_IFNAME, {name.data(), name.size() + 1});
        }
        if (i.mac)
        {
            appendRTAttr(msgBuf, IFLA_ADDRESS,
                         stdplus::raw::asView<char>(*i.mac));
        }
        if (i.mtu)
        {
            appendRTAttr(msgBuf, IFLA_MTU, stdplus::raw::asView<char>(*i.mtu));
        }
        auto& hdr = *reinterpret_cast<nlmsghdr*>(msgBuf.data() + nlbegin);
        hdr.nlmsg_len = msgBuf.size() - nlbegin;
        hdr.nlmsg_type = RTM_NEWLINK;
        hdr.nlmsg_flags = NLM_F_MULTI;
        msgBuf.resize(NLMSG_ALIGN(msgBuf.size()), '\0');
    }
    const auto nlbegin = msgBuf.size();
    msgBuf.append(NLMSG_SPACE(0), '\0');
    auto& hdr = *reinterpret_cast<nlmsghdr*>(msgBuf.data() + nlbegin);
    hdr.nlmsg_len = NLMSG_LENGTH(0);
    hdr.nlmsg_type = NLMSG_DONE;
    hdr.nlmsg_flags = NLM_F_MULTI;

    msgs.emplace(std::move(msgBuf));
    return in.size();
}

ssize_t sendmsg_ack(std::queue<std::string>& msgs, std::string_view in)
{
    nlmsgerr ack{};
    nlmsghdr hdr{};
    hdr.nlmsg_len = NLMSG_LENGTH(sizeof(ack));
    hdr.nlmsg_type = NLMSG_ERROR;
    auto& out = msgs.emplace(hdr.nlmsg_len, '\0');
    memcpy(out.data(), &hdr, sizeof(hdr));
    memcpy(NLMSG_DATA(out.data()), &ack, sizeof(ack));
    return in.size();
}

extern "C" {

int ioctl(int fd, unsigned long int request, ...)
{
    va_list vl;
    va_start(vl, request);
    void* data = va_arg(vl, void*);
    va_end(vl);

    auto req = reinterpret_cast<ifreq*>(data);
    if (request == SIOCGIFFLAGS)
    {
        auto it = mock_if.find(req->ifr_name);
        if (it == mock_if.end())
        {
            errno = ENXIO;
            return -1;
        }
        req->ifr_flags = it->second.flags;
        return 0;
    }
    else if (request == SIOCGIFMTU)
    {
        auto it = mock_if.find(req->ifr_name);
        if (it == mock_if.end())
        {
            errno = ENXIO;
            return -1;
        }
        if (!it->second.mtu)
        {
            errno = EOPNOTSUPP;
            return -1;
        }
        req->ifr_mtu = *it->second.mtu;
        return 0;
    }

    static auto real_ioctl =
        reinterpret_cast<decltype(&ioctl)>(dlsym(RTLD_NEXT, "ioctl"));
    return real_ioctl(fd, request, data);
}

int socket(int domain, int type, int protocol)
{
    static auto real_socket =
        reinterpret_cast<decltype(&socket)>(dlsym(RTLD_NEXT, "socket"));
    int fd = real_socket(domain, type, protocol);
    if (domain == AF_NETLINK && !(type & SOCK_RAW))
    {
        fprintf(stderr, "Netlink sockets must be RAW\n");
        abort();
    }
    if (domain == AF_NETLINK && protocol == NETLINK_ROUTE)
    {
        mock_rtnetlinks[fd] = {};
    }
    return fd;
}

int close(int fd)
{
    auto it = mock_rtnetlinks.find(fd);
    if (it != mock_rtnetlinks.end())
    {
        mock_rtnetlinks.erase(it);
    }

    static auto real_close =
        reinterpret_cast<decltype(&close)>(dlsym(RTLD_NEXT, "close"));
    return real_close(fd);
}

ssize_t sendmsg(int sockfd, const struct msghdr* msg, int flags)
{
    auto it = mock_rtnetlinks.find(sockfd);
    if (it == mock_rtnetlinks.end())
    {
        static auto real_sendmsg =
            reinterpret_cast<decltype(&sendmsg)>(dlsym(RTLD_NEXT, "sendmsg"));
        return real_sendmsg(sockfd, msg, flags);
    }
    auto& msgs = it->second;

    validateMsgHdr(msg);
    if (!msgs.empty())
    {
        fprintf(stderr, "Unread netlink responses\n");
        abort();
    }

    ssize_t ret;
    std::string_view iov(reinterpret_cast<char*>(msg->msg_iov[0].iov_base),
                         msg->msg_iov[0].iov_len);

    ret = sendmsg_link_dump(msgs, iov);
    if (ret != 0)
    {
        return ret;
    }

    ret = sendmsg_ack(msgs, iov);
    if (ret != 0)
    {
        return ret;
    }

    errno = ENOSYS;
    return -1;
}

ssize_t recvmsg(int sockfd, struct msghdr* msg, int flags)
{
    auto it = mock_rtnetlinks.find(sockfd);
    if (it == mock_rtnetlinks.end())
    {
        static auto real_recvmsg =
            reinterpret_cast<decltype(&recvmsg)>(dlsym(RTLD_NEXT, "recvmsg"));
        return real_recvmsg(sockfd, msg, flags);
    }
    auto& msgs = it->second;

    validateMsgHdr(msg);
    constexpr size_t required_buf_size = 8192;
    if (msg->msg_iov[0].iov_len < required_buf_size)
    {
        fprintf(stderr, "recvmsg iov too short: %zu\n",
                msg->msg_iov[0].iov_len);
        abort();
    }
    if (msgs.empty())
    {
        fprintf(stderr, "No pending netlink responses\n");
        abort();
    }

    ssize_t ret = 0;
    auto data = reinterpret_cast<char*>(msg->msg_iov[0].iov_base);
    while (!msgs.empty())
    {
        const auto& msg = msgs.front();
        if (NLMSG_ALIGN(ret) + msg.size() > required_buf_size)
        {
            break;
        }
        ret = NLMSG_ALIGN(ret);
        memcpy(data + ret, msg.data(), msg.size());
        ret += msg.size();
        msgs.pop();
    }
    return ret;
}

} // extern "C"
