/*
 *  Copyright (C) 2023 Savoir-faire Linux Inc.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
#include "dsh.h"
#include "../common.h"
#include <opendht/log.h>
#include <opendht/crypto.h>

#include <asio/io_context.hpp>
#include <sys/types.h>
#include <sys/wait.h>
namespace dhtnet {

const int READ_END = 0;
const int WRITE_END = 1;

void
create_pipe(int apipe[2])
{
#ifdef __APPLE__
    if (pipe(apipe) < 0)
        perror("pipe");

    if (fcntl(apipe[0], F_SETFD, FD_CLOEXEC) < 0)
        perror("unable to set pipe FD_CLOEXEC");

    if (fcntl(apipe[1], F_SETFD, FD_CLOEXEC) < 0)
        perror("unable to set pipe FD_CLOEXEC");
#else
    if (pipe2(apipe, O_CLOEXEC) == -1) {
        perror("pipe2");
        exit(EXIT_FAILURE);
    }
#endif
}

void
child_proc(const int in_pipe[2],
           const int out_pipe[2],
           const int error_pipe[2],
           const std::string& name)
{
    // close unused write end of input pipe and read end of output pipe
    close(in_pipe[WRITE_END]);
    close(out_pipe[READ_END]);
    close(error_pipe[READ_END]);

    // replace stdin with input pipe
    if (dup2(in_pipe[READ_END], STDIN_FILENO) == -1) {
        perror("dup2: error replacing stdin");
        exit(EXIT_FAILURE);
    }

    // replace stdout with output pipe
    if (dup2(out_pipe[WRITE_END], STDOUT_FILENO) == -1) {
        perror("dup2: error replacing stdout");
        exit(EXIT_FAILURE);
    }
    // replace stderr with error pipe
    if (dup2(error_pipe[WRITE_END], STDERR_FILENO) == -1) {
        perror("dup2: error replacing stderr");
        exit(EXIT_FAILURE);
    }

    // prepare arguments
    const char* args[] = {name.c_str(), NULL};
    // execute subprocess
    execvp(args[0], const_cast<char* const*>(args));

    // if execv returns, an error occurred
    perror("execvp");
    exit(EXIT_FAILURE);
}

dhtnet::Dsh::Dsh(dht::crypto::Identity identity,
                 const std::string& bootstrap,
                 const std::string& turn_host,
                 const std::string& turn_user,
                 const std::string& turn_pass,
                 const std::string& turn_realm,
                 bool anonymous)
    :logger(dht::log::getStdLogger()),
    ioContext(std::make_shared<asio::io_context>()),
    iceFactory(std::make_shared<IceTransportFactory>(logger)),
    certStore(std::make_shared<tls::CertificateStore>(cachePath()/"certstore", logger)),
    trustStore(std::make_shared<tls::TrustStore>(*certStore))
{
    auto ca = identity.second->issuer;
    trustStore->setCertificateStatus(ca->getId().toString(), tls::TrustStore::PermissionStatus::ALLOWED);
    // Build a server
    auto config = connectionManagerConfig(identity,
                                          bootstrap,
                                          logger,
                                          certStore,
                                          ioContext,
                                          iceFactory);
    // create a connection manager
    connectionManager = std::make_unique<ConnectionManager>(std::move(config));

    connectionManager->onDhtConnected(identity.first->getPublicKey());
    connectionManager->onICERequest([this,identity,anonymous](const DeviceId& deviceId ) { // handle ICE request
        return trustStore->isAllowed(*certStore->getCertificate(deviceId.toString()), anonymous);
    });

    std::mutex mtx;
    std::unique_lock lk {mtx};

    connectionManager->onChannelRequest(
        [&](const std::shared_ptr<dht::crypto::Certificate>&, const std::string& name) {
            // handle channel request
            if (logger)
                logger->debug("Channel request received");
            return true;
        });

    connectionManager->onConnectionReady([&](const DeviceId&,
                                             const std::string& name,
                                             std::shared_ptr<ChannelSocket> socket) {
        // handle connection ready
        try {
            // Create a pipe for communication with the  subprocess
            // create pipes
            int in_pipe[2], out_pipe[2], error_pipe[2];
            create_pipe(in_pipe);
            create_pipe(out_pipe);
            create_pipe(error_pipe);

            ioContext->notify_fork(asio::io_context::fork_prepare);

            // Fork to create a child process
            pid_t pid = fork();
            if (pid == -1) {
                perror("fork");
                return EXIT_FAILURE;
            } else if (pid == 0) { // Child process
                ioContext->notify_fork(asio::io_context::fork_child);
                child_proc(in_pipe, out_pipe, error_pipe, name);
                return EXIT_SUCCESS; // never reached
            } else {
                ioContext->notify_fork(asio::io_context::fork_parent);

                // close unused read end of input pipe and write end of output pipe
                close(in_pipe[READ_END]);
                close(out_pipe[WRITE_END]);
                close(error_pipe[WRITE_END]);

                asio::io_context& ioContextRef = *ioContext;
                // create stream descriptors
                auto inStream
                    = std::make_shared<asio::posix::stream_descriptor>(ioContextRef.get_executor(),
                                                                       in_pipe[WRITE_END]);
                auto outStream
                    = std::make_shared<asio::posix::stream_descriptor>(ioContextRef.get_executor(),
                                                                       out_pipe[READ_END]);
                auto errorStream
                    = std::make_shared<asio::posix::stream_descriptor>(ioContextRef.get_executor(),
                                                                       error_pipe[READ_END]);

                if (socket) {
                    socket->setOnRecv([this, socket, inStream](const uint8_t* data, size_t size) {
                        auto data_copy = std::make_shared<std::vector<uint8_t>>(data, data + size);
                        // write on pipe to sub child
                        std::error_code ec;
                        asio::async_write(*inStream,
                                          asio::buffer(*data_copy),
                                          [data_copy, this](const std::error_code& error,
                                                            std::size_t bytesWritten) {
                                              if (error) {
                                                  if (logger)
                                                      logger->error("Write error: {}",
                                                                    error.message());
                                              }
                                          });
                        return size;
                    });

                    // read from pipe to sub child

                    // Create a buffer to read data into
                    auto buffer = std::make_shared<std::vector<uint8_t>>(BUFFER_SIZE);

                    // Create a shared_ptr to the stream_descriptor
                    readFromPipe(socket, outStream, buffer);
                    readFromPipe(socket, errorStream, buffer);

                    return EXIT_SUCCESS;
                }
            }

        } catch (const std::exception& e) {
            if (logger)
                logger->error("Error: {}", e.what());
        }
        return 0;
    });
}

dhtnet::Dsh::Dsh(dht::crypto::Identity identity,
                 const std::string& bootstrap,
                 dht::InfoHash peer_id,
                 const std::string& binary,
                 const std::string& turn_host,
                 const std::string& turn_user,
                 const std::string& turn_pass,
                 const std::string& turn_realm)
    : Dsh(identity, bootstrap, turn_host, turn_user, turn_pass, turn_realm, false)
{
    // Build a client
    std::condition_variable cv;
    connectionManager->connectDevice(
        peer_id, binary, [&](std::shared_ptr<ChannelSocket> socket, const dht::InfoHash&) {
            if (socket) {
                socket->setOnRecv([this, socket](const uint8_t* data, size_t size) {
                    std::cout.write((const char*) data, size);
                    std::cout.flush();
                    return size;
                });
                // Create a buffer to read data into
                auto buffer = std::make_shared<std::vector<uint8_t>>(BUFFER_SIZE);

                // Create a shared_ptr to the stream_descriptor
                auto stdinPipe = std::make_shared<asio::posix::stream_descriptor>(*ioContext,
                                                                                  ::dup(
                                                                                      STDIN_FILENO));
                readFromPipe(socket, stdinPipe, buffer);

                socket->onShutdown([this]() {
                    if (logger)
                        logger->debug("Exit program");
                    ioContext->stop();
                });
            }
        });

    connectionManager->onConnectionReady([&](const DeviceId&,
                                             const std::string& name,
                                             std::shared_ptr<ChannelSocket> socket_received) {
        if (logger)
            logger->debug("Connected!");
    });
}

void
dhtnet::Dsh::run()
{
    auto work = asio::make_work_guard(*ioContext);
    ioContext->run();
}

dhtnet::Dsh::~Dsh()
{
    ioContext->stop();
}

} // namespace dhtnet