#include <stdplus/print.hpp>
#include <util/common.hpp>

#include <array>
#include <cstdlib>
#include <format>
#include <memory>
#include <mutex>
#include <optional>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

std::mutex mMutex;
std::unordered_map<std::string, std::string> udevIdToPortMap;

/**
 * @brief Execute a CLI command and return the command line result
 *
 * @param[in] cmd - Command to be executed
 *
 * @return Output of console
 */
std::string exec(const char* cmd)
{
    std::array<char, 128> buffer;
    std::string result;
    std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
    if (!pipe)
    {
        throw std::runtime_error("popen() failed!");
    }
    while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
    {
        result += buffer.data();
    }
    return result;
}

/**
 * @brief Gets the already set MCTP links on the system
 *
 * @param[in] mctpLinkString - Console output for mctp link command
 *
 * @return list of mctp serial ports
 */
std::optional<std::unordered_set<std::string>>
    getActiveMctpPorts(std::string mctpLinkString)
{
    size_t pos = 0;
    std::string delimiter = "\n";
    std::unordered_set<std::string> mctpPorts;
    while ((pos = mctpLinkString.find(delimiter)) != std::string::npos)
    {
        std::string token = mctpLinkString.substr(0, pos);
        size_t p = token.find("mctpserial");
        if (p != std::string::npos)
        {
            // Take the first 11 characters from the output string
            // That will be of format `mctpserial0` - 11 chars
            mctpPorts.emplace(token.substr(p, 11));
        }
        mctpLinkString = mctpLinkString.substr(pos + delimiter.length());
    }

    if (!mctpLinkString.empty())
    {
        size_t p = mctpLinkString.find("mctpserial");
        if (p != std::string::npos)
        {
            // Works only for 9 devices
            mctpPorts.emplace(mctpLinkString.substr(p, 11));
        }
    }

    if (mctpPorts.empty())
    {
        return std::nullopt;
    }
    return mctpPorts;
}

/**
 * @brief Extract the name from the command line result
 *
 * "dev mctpserial0 index 13 address 0x(no-addr) net 7 mtu 68 up"
 *
 * To up link mctpserial0 for MCTP we need to extract the added "mctpserial0"
 *
 * @param[in] preSetupOutput - mctp link output pre setup of new port
 * @param[in] postSetupOutput - mctp link output post setup of new port
 *
 * @return returns the newly added mctp port name
 */
std::optional<std::string> extractNewName(const std::string& preSetupOutput,
                                          const std::string& postSetupOutput)
{
    std::optional<std::unordered_set<std::string>> mctpPortsPreOpt =
        getActiveMctpPorts(preSetupOutput);
    std::unordered_set<std::string> preSetupPorts;
    if (mctpPortsPreOpt.has_value())
    {
        preSetupPorts = mctpPortsPreOpt.value();
    }

    std::optional<std::unordered_set<std::string>> mctpPortsPostOpt =
        getActiveMctpPorts(postSetupOutput);
    if (mctpPortsPostOpt.has_value())
    {
        std::unordered_set<std::string> postSetupPorts =
            mctpPortsPostOpt.value();
        for (auto port : postSetupPorts)
        {
            auto it = preSetupPorts.find(port);
            if (it == preSetupPorts.end())
            {
                return port;
            }
        }
    }
    stdplus::print(stderr, "Link command failed\n");
    return std::nullopt;
}

/**
 * @brief Creating a unique network id from the udevId for a particular RDE
 * device
 *
 * Currently this takes the udev id and adds the digits in it to create a net id
 * For instance, for udev_id "1_1_4_1" the network id would be "7" (Sum of all
 * digits)
 *
 * @param[in] udevId - Udev id of the device
 *
 * @return network id
 */
int createNetIdFromUdevId(std::string udevId)
{
    // Creates a net id for a udev id by adding all the digits in the path
    // 1_1_4_1 = 7
    std::string delimiter = "_";
    int netId = 0;
    size_t pos = 0;
    std::string token;

    while ((pos = udevId.find(delimiter)) != std::string::npos)
    {
        token = udevId.substr(0, pos);
        netId = netId + stoi(token);
        udevId.erase(0, pos + delimiter.length());
    }

    if (!udevId.empty())
        return netId + stoi(udevId);
    return netId;
}

/**
 * @brief kill all the mctp serial links produced after executing the cmd in
 * in param
 *
 * @param[in] - grepLinkCmd: Command for getting mctp serial links
 */
void killMctpSerialLinks(const std::string& grepLinkCmd)
{
    std::string output = exec(grepLinkCmd.c_str());
    std::vector<int> pids;
    std::istringstream iss(output);
    if (DEBUG)
    {
        stdplus::print(stderr, "Output for {}: {}\n", grepLinkCmd, output);
    }
    std::string line;
    while (std::getline(iss, line))
    {
        // Create a stringstream from the input line
        std::istringstream lineStream(line);
        int pid;
        if ((lineStream >> pid) && (line.find("grep") == std::string::npos) &&
            (line.find("ps") == std::string::npos))
        {
            pids.emplace_back(pid);
        }
    }

    for (const int& pid : pids)
    {
        std::string killCmd = std::format("kill -9 {}", pid);
        stdplus::print(stderr, "Executing: {}\n", killCmd);
        exec(killCmd.c_str());
    }
    if (!pids.empty())
    {
        // Sleep since unlinking might take a bit of time
        sleep(2);
    }
}

/**
 * @brief Clean up existing mctp links for a particular device
 *
 * @param[in] - udevId: device id
 */
void cleanupMctpLink(const std::string& udevId)
{
    stdplus::print(stderr,
                   "Look for exisiting MCTP serial link for udevId: {}...\n",
                   udevId);

    // check for the particular device if any mctp link present
    auto it = udevIdToPortMap.find(udevId);
    if (it != udevIdToPortMap.end())
    {
        std::string port = it->second;
        if (DEBUG)
        {
            stdplus::print(stderr,
                           "Looking at previous dev path: {} for udevId: {}\n",
                           port, udevId);
        }
        std::string grepSerialLinks =
            std::format("ps | grep \"mctp link serial {}\"", port);
        killMctpSerialLinks(grepSerialLinks);
    }
    else if (DEBUG)
    {
        stdplus::print(stderr, "No MCTP serial path found for udevId: {}\n",
                       udevId);
    }
}

/**
 * @brief Sets up MCTP on on "mctpserial" port
 *
 * **Currently this has some random sleeps attached as it takes some time to
 * bring MCTP up. This function is only executed when a device reboots or the
 * system boots**
 *
 * @param[in] port - the port at which MCTP is to be setup, format- "/dev/tty*"
 * @param[in] udevId - udev id of the RDE device, which is a unique identifier
 * and remains same for the device even after reboots
 *
 * @return Returns 0 if success else -1
 */
int setupOnePort(const std::string& port, const std::string& udevId)
{
    // TODO(b/284167548): Find an efficient way to set up MCTP without using CLI
    // commands This might help us get rid of sleeps
    // Wait for some time until the previous MCTP is set up if any
    sleep(2);

    // Mutex lock so that another device setup doesn't hinder the MCTP setup
    mMutex.lock();
    bool setupComplete = false;
    std::string mctpLinkShow = "mctp link show";
    // lock mutex
    int networkId;
    for (int retryCounter = 0; retryCounter < MAX_RETRIES_MCTP_SOCK_FAILURE;
         retryCounter++)
    {
        stdplus::print(
            stderr,
            "Triggering MCTP setup on port: {} with retry counter: {}\n", port,
            retryCounter);

        // Remove the existing mctp links if running for the first time
        if (udevIdToPortMap.empty())
        {
            std::string grepAllMctpLinks = "ps | grep \"mctp link serial\"";
            stdplus::print(
                stderr,
                "Finding any existing MCTP serial links on daemon bootup...\n");
            killMctpSerialLinks(grepAllMctpLinks);
        }

        // Executing link command pre setup to see current active ports
        std::string linkResultPreSetup = exec(mctpLinkShow.c_str());
        if (DEBUG)
        {
            stdplus::print(stderr, "Executing linkResult pre setup: {}\n",
                           linkResultPreSetup);
        }

        std::string linkCmd = std::format("mctp link serial {} &", port);
        if (DEBUG)
        {
            stdplus::print(stderr, "Executing: {}\n", linkCmd);
        }

        int sysRc = system(linkCmd.c_str());
        if (sysRc)
        {
            stdplus::print(
                stderr, "Error in setting up mctp link with return code: {}\n",
                std::to_string(sysRc));
            continue;
        }

        // Update the udevId map with new dev path link
        udevIdToPortMap.erase(udevId);
        udevIdToPortMap.emplace(udevId, port);

        // MCTP link command takes some time to finish - hence a sleep of 5s
        sleep(5);
        // Extract name:
        std::string mctpName;
        std::string linkResult = exec(mctpLinkShow.c_str());
        if (DEBUG)
        {
            stdplus::print(stderr, "Executing linkResult: {}\n", linkResult);
        }

        std::optional<std::string> mctpNameOpt =
            extractNewName(linkResultPreSetup, linkResult);
        if (mctpNameOpt.has_value())
        {
            mctpName = mctpNameOpt.value();
        }
        else
        {
            stdplus::print(
                stderr,
                "No mctp serial connection found. MCTP Link failed...\n");
            continue;
        }

        networkId = createNetIdFromUdevId(udevId);
        std::string upCmd = std::format("mctp link set {} network {} up",
                                        mctpName, std::to_string(networkId));
        if (DEBUG)
        {
            stdplus::print(stderr, "Executing upcmd: {}\n", upCmd);
        }

        std::string networkSetResponse = exec(upCmd.c_str());
        if (networkSetResponse.find("invalid") != std::string::npos)
        {
            stdplus::print(stderr, "Network setup failure... retrying\n");
            continue;
        }

        // Setting network id for a port takes some time to setup
        sleep(5);
        // Setting up local addresses
        std::string localAddrCmd =
            std::format("mctp addr add 8 dev {}", mctpName);
        std::string routeCmd = std::format("mctp route add 9 via {}", mctpName);
        if (DEBUG)
        {
            stdplus::print(stderr, "Executing local addr: {}\n", localAddrCmd);
        }

        exec(localAddrCmd.c_str());
        if (DEBUG)
        {
            stdplus::print(stderr, "Executing routeCmd: {}\n", routeCmd);
        }
        exec(routeCmd.c_str());
        // Setting up routes and local address takes time
        sleep(5);

        setupComplete = true;
        stdplus::print(stderr, "Setup completed for MCTP port: {}\n", port);
        break;
    }
    // unlock mutex
    mMutex.unlock();
    if (setupComplete)
    {
        return networkId;
    }
    return -1;
}
