//===-- lldb-gdbserver.cpp --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef _WIN32
#include <signal.h>
#include <unistd.h>
#endif

// C++ Includes

// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"

#include "lldb/Core/Error.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/HostGetOpt.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Target/Platform.h"
#include "Acceptor.h"
#include "LLDBServerUtilities.h"
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"

#ifndef LLGS_PROGRAM_NAME
#define LLGS_PROGRAM_NAME "lldb-server"
#endif

#ifndef LLGS_VERSION_STR
#define LLGS_VERSION_STR "local_build"
#endif

using namespace llvm;
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::lldb_server;
using namespace lldb_private::process_gdb_remote;

//----------------------------------------------------------------------
// option descriptors for getopt_long_only()
//----------------------------------------------------------------------

static int g_debug = 0;
static int g_verbose = 0;

static struct option g_long_options[] =
{
    { "debug",              no_argument,        &g_debug,           1   },
    { "platform",           required_argument,  NULL,               'p' },
    { "verbose",            no_argument,        &g_verbose,         1   },
    { "log-file",           required_argument,  NULL,               'l' },
    { "log-channels",       required_argument,  NULL,               'c' },
    { "attach",             required_argument,  NULL,               'a' },
    { "named-pipe",         required_argument,  NULL,               'N' },
    { "pipe",               required_argument,  NULL,               'U' },
    { "native-regs",        no_argument,        NULL,               'r' },  // Specify to use the native registers instead of the gdb defaults for the architecture.  NOTE: this is a do-nothing arg as it's behavior is default now.  FIXME remove call from lldb-platform.
    { "reverse-connect",    no_argument,        NULL,               'R' },  // Specifies that llgs attaches to the client address:port rather than llgs listening for a connection from address on port.
    { "setsid",             no_argument,        NULL,               'S' },  // Call setsid() to make llgs run in its own session.
    { NULL,                 0,                  NULL,               0   }
};


//----------------------------------------------------------------------
// Watch for signals
//----------------------------------------------------------------------
static int g_sigpipe_received = 0;
static int g_sighup_received_count = 0;

#ifndef _WIN32

static void
signal_handler(int signo)
{
    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));

    fprintf (stderr, "lldb-server:%s received signal %d\n", __FUNCTION__, signo);
    if (log)
        log->Printf ("lldb-server:%s received signal %d", __FUNCTION__, signo);

    switch (signo)
    {
    case SIGPIPE:
        g_sigpipe_received = 1;
        break;
    }
}

static void
sighup_handler(MainLoopBase &mainloop)
{
    ++g_sighup_received_count;

    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
    if (log)
        log->Printf ("lldb-server:%s swallowing SIGHUP (receive count=%d)", __FUNCTION__, g_sighup_received_count);

    if (g_sighup_received_count >= 2)
        mainloop.RequestTermination();
}
#endif // #ifndef _WIN32

static void
display_usage (const char *progname, const char* subcommand)
{
    fprintf(stderr, "Usage:\n  %s %s "
            "[--log-file log-file-name] "
            "[--log-channels log-channel-list] "
            "[--platform platform_name] "
            "[--setsid] "
            "[--named-pipe named-pipe-path] "
            "[--native-regs] "
            "[--attach pid] "
            "[[HOST]:PORT] "
            "[-- PROGRAM ARG1 ARG2 ...]\n", progname, subcommand);
    exit(0);
}

static void
dump_available_platforms (FILE *output_file)
{
    fprintf (output_file, "Available platform plugins:\n");
    for (int i = 0; ; ++i)
    {
        const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (i);
        const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (i);

        if (!plugin_name || !plugin_desc)
            break;

        fprintf (output_file, "%s\t%s\n", plugin_name, plugin_desc);
    }

    if ( Platform::GetHostPlatform () )
    {
        // add this since the default platform doesn't necessarily get registered by
        // the plugin name (e.g. 'host' doesn't show up as a
        // registered platform plugin even though it's the default).
        fprintf (output_file, "%s\tDefault platform for this host.\n", Platform::GetHostPlatform ()->GetPluginName ().AsCString ());
    }
}

static lldb::PlatformSP
setup_platform (const std::string &platform_name)
{
    lldb::PlatformSP platform_sp;

    if (platform_name.empty())
    {
        printf ("using the default platform: ");
        platform_sp = Platform::GetHostPlatform ();
        printf ("%s\n", platform_sp->GetPluginName ().AsCString ());
        return platform_sp;
    }

    Error error;
    platform_sp = Platform::Create (lldb_private::ConstString(platform_name), error);
    if (error.Fail ())
    {
        // the host platform isn't registered with that name (at
        // least, not always.  Check if the given name matches
        // the default platform name.  If so, use it.
        if ( Platform::GetHostPlatform () && ( Platform::GetHostPlatform ()->GetPluginName () == ConstString (platform_name.c_str()) ) )
        {
            platform_sp = Platform::GetHostPlatform ();
        }
        else
        {
            fprintf (stderr, "error: failed to create platform with name '%s'\n", platform_name.c_str());
            dump_available_platforms (stderr);
            exit (1);
        }
    }
    printf ("using platform: %s\n", platform_name.c_str ());

    return platform_sp;
}

void
handle_attach_to_pid (GDBRemoteCommunicationServerLLGS &gdb_server, lldb::pid_t pid)
{
    Error error = gdb_server.AttachToProcess (pid);
    if (error.Fail ())
    {
        fprintf (stderr, "error: failed to attach to pid %" PRIu64 ": %s\n", pid, error.AsCString());
        exit(1);
    }
}

void
handle_attach_to_process_name (GDBRemoteCommunicationServerLLGS &gdb_server, const std::string &process_name)
{
    // FIXME implement.
}

void
handle_attach (GDBRemoteCommunicationServerLLGS &gdb_server, const std::string &attach_target)
{
    assert (!attach_target.empty () && "attach_target cannot be empty");

    // First check if the attach_target is convertible to a long. If so, we'll use it as a pid.
    char *end_p = nullptr;
    const long int pid = strtol (attach_target.c_str (), &end_p, 10);

    // We'll call it a match if the entire argument is consumed.
    if (end_p && static_cast<size_t> (end_p - attach_target.c_str ()) == attach_target.size ())
        handle_attach_to_pid (gdb_server, static_cast<lldb::pid_t> (pid));
    else
        handle_attach_to_process_name (gdb_server, attach_target);
}

void
handle_launch (GDBRemoteCommunicationServerLLGS &gdb_server, int argc, const char *const argv[])
{
    Error error;
    error = gdb_server.SetLaunchArguments (argv, argc);
    if (error.Fail ())
    {
        fprintf (stderr, "error: failed to set launch args for '%s': %s\n", argv[0], error.AsCString());
        exit(1);
    }

    unsigned int launch_flags = eLaunchFlagStopAtEntry | eLaunchFlagDebug;

    error = gdb_server.SetLaunchFlags (launch_flags);
    if (error.Fail ())
    {
        fprintf (stderr, "error: failed to set launch flags for '%s': %s\n", argv[0], error.AsCString());
        exit(1);
    }

    error = gdb_server.LaunchProcess ();
    if (error.Fail ())
    {
        fprintf (stderr, "error: failed to launch '%s': %s\n", argv[0], error.AsCString());
        exit(1);
    }
}

Error
writeSocketIdToPipe(Pipe &port_pipe, const std::string &socket_id)
{
    size_t bytes_written = 0;
    // Write the port number as a C string with the NULL terminator.
    return port_pipe.Write(socket_id.c_str(), socket_id.size() + 1, bytes_written);
}

Error
writeSocketIdToPipe(const char *const named_pipe_path, const std::string &socket_id)
{
    Pipe port_name_pipe;
    // Wait for 10 seconds for pipe to be opened.
    auto error = port_name_pipe.OpenAsWriterWithTimeout(named_pipe_path, false,
            std::chrono::seconds{10});
    if (error.Fail())
        return error;
    return writeSocketIdToPipe(port_name_pipe, socket_id);
}

Error
writeSocketIdToPipe(int unnamed_pipe_fd, const std::string &socket_id)
{
#if defined(_WIN32)
    return Error("Unnamed pipes are not supported on Windows.");
#else
    Pipe port_pipe{Pipe::kInvalidDescriptor, unnamed_pipe_fd};
    return writeSocketIdToPipe(port_pipe, socket_id);
#endif
}

void
ConnectToRemote(MainLoop &mainloop, GDBRemoteCommunicationServerLLGS &gdb_server,
        bool reverse_connect, const char *const host_and_port,
        const char *const progname, const char *const subcommand,
        const char *const named_pipe_path, int unnamed_pipe_fd)
{
    Error error;

    if (host_and_port && host_and_port[0])
    {
        // Parse out host and port.
        std::string final_host_and_port;
        std::string connection_host;
        std::string connection_port;
        uint32_t connection_portno = 0;

        // If host_and_port starts with ':', default the host to be "localhost" and expect the remainder to be the port.
        if (host_and_port[0] == ':')
            final_host_and_port.append ("localhost");
        final_host_and_port.append (host_and_port);

        const std::string::size_type colon_pos = final_host_and_port.find (':');
        if (colon_pos != std::string::npos)
        {
            connection_host = final_host_and_port.substr (0, colon_pos);
            connection_port = final_host_and_port.substr (colon_pos + 1);
            connection_portno = StringConvert::ToUInt32 (connection_port.c_str (), 0);
        }

        std::unique_ptr<Connection> connection_up;

        if (reverse_connect)
        {
            // llgs will connect to the gdb-remote client.

            // Ensure we have a port number for the connection.
            if (connection_portno == 0)
            {
                fprintf (stderr, "error: port number must be specified on when using reverse connect");
                exit (1);
            }

            // Build the connection string.
            char connection_url[512];
            snprintf(connection_url, sizeof(connection_url), "connect://%s", final_host_and_port.c_str ());

            // Create the connection.
            connection_up.reset(new ConnectionFileDescriptor);
            auto connection_result = connection_up->Connect (connection_url, &error);
            if (connection_result != eConnectionStatusSuccess)
            {
                fprintf (stderr, "error: failed to connect to client at '%s' (connection status: %d)", connection_url, static_cast<int> (connection_result));
                exit (-1);
            }
            if (error.Fail ())
            {
                fprintf (stderr, "error: failed to connect to client at '%s': %s", connection_url, error.AsCString ());
                exit (-1);
            }
        }
        else
        {
            std::unique_ptr<Acceptor> acceptor_up(Acceptor::Create(final_host_and_port, false, error));
            if (error.Fail())
            {
                fprintf(stderr, "failed to create acceptor: %s", error.AsCString());
                exit(1);
            }
            error = acceptor_up->Listen(1);
            if (error.Fail())
            {
                fprintf(stderr, "failed to listen: %s\n", error.AsCString());
                exit(1);
            }
            const std::string socket_id = acceptor_up->GetLocalSocketId();
            if (!socket_id.empty())
            {
                // If we have a named pipe to write the socket id back to, do that now.
                if (named_pipe_path && named_pipe_path[0])
                {
                    error = writeSocketIdToPipe (named_pipe_path, socket_id);
                    if (error.Fail ())
                        fprintf (stderr, "failed to write to the named pipe \'%s\': %s",
                                 named_pipe_path, error.AsCString());
                }
                // If we have an unnamed pipe to write the socket id back to, do that now.
                else if (unnamed_pipe_fd >= 0)
                {
                    error = writeSocketIdToPipe(unnamed_pipe_fd, socket_id);
                    if (error.Fail())
                        fprintf(stderr, "failed to write to the unnamed pipe: %s",
                                error.AsCString());
                }
            }
            else
            {
                fprintf (stderr, "unable to get the socket id for the listening connection\n");
            }

            Connection* conn = nullptr;
            error = acceptor_up->Accept(false, conn);
            if (error.Fail())
            {
                printf ("failed to accept new connection: %s\n", error.AsCString());
                exit(1);
            }
            connection_up.reset(conn);
        }
        error = gdb_server.InitializeConnection (std::move(connection_up));
        if (error.Fail())
        {
            fprintf(stderr, "Failed to initialize connection: %s\n", error.AsCString());
            exit(-1);
        }
        printf ("Connection established.\n");
    }
}

//----------------------------------------------------------------------
// main
//----------------------------------------------------------------------
int
main_gdbserver (int argc, char *argv[])
{
    Error error;
    MainLoop mainloop;
#ifndef _WIN32
    // Setup signal handlers first thing.
    signal (SIGPIPE, signal_handler);
    MainLoop::SignalHandleUP sighup_handle = mainloop.RegisterSignal(SIGHUP, sighup_handler, error);
#endif
#ifdef __linux__
    // Block delivery of SIGCHLD on linux. NativeProcessLinux will read it using signalfd.
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGCHLD);
    pthread_sigmask(SIG_BLOCK, &set, NULL);
#endif

    const char *progname = argv[0];
    const char *subcommand = argv[1];
    argc--;
    argv++;
    int long_option_index = 0;
    int ch;
    std::string platform_name;
    std::string attach_target;
    std::string named_pipe_path;
    std::string log_file;
    StringRef log_channels; // e.g. "lldb process threads:gdb-remote default:linux all"
    int unnamed_pipe_fd = -1;
    bool reverse_connect = false;

    // ProcessLaunchInfo launch_info;
    ProcessAttachInfo attach_info;

    bool show_usage = false;
    int option_error = 0;
#if __GLIBC__
    optind = 0;
#else
    optreset = 1;
    optind = 1;
#endif

    std::string short_options(OptionParser::GetShortOptionString(g_long_options));

    while ((ch = getopt_long_only(argc, argv, short_options.c_str(), g_long_options, &long_option_index)) != -1)
    {
        switch (ch)
        {
        case 0:   // Any optional that auto set themselves will return 0
            break;

        case 'l': // Set Log File
            if (optarg && optarg[0])
                log_file.assign(optarg);
            break;

        case 'c': // Log Channels
            if (optarg && optarg[0])
                log_channels = StringRef(optarg);
            break;

        case 'p': // platform name
            if (optarg && optarg[0])
                platform_name = optarg;
            break;

        case 'N': // named pipe
            if (optarg && optarg[0])
                named_pipe_path = optarg;
            break;

        case 'U': // unnamed pipe
            if (optarg && optarg[0])
                unnamed_pipe_fd = StringConvert::ToUInt32(optarg, -1);

        case 'r':
            // Do nothing, native regs is the default these days
            break;

        case 'R':
            reverse_connect = true;
            break;

#ifndef _WIN32
        case 'S':
            // Put llgs into a new session. Terminals group processes
            // into sessions and when a special terminal key sequences
            // (like control+c) are typed they can cause signals to go out to
            // all processes in a session. Using this --setsid (-S) option
            // will cause debugserver to run in its own sessions and be free
            // from such issues.
            //
            // This is useful when llgs is spawned from a command
            // line application that uses llgs to do the debugging,
            // yet that application doesn't want llgs receiving the
            // signals sent to the session (i.e. dying when anyone hits ^C).
            {
                const ::pid_t new_sid = setsid();
                if (new_sid == -1)
                {
                    const char *errno_str = strerror(errno);
                    fprintf (stderr, "failed to set new session id for %s (%s)\n", LLGS_PROGRAM_NAME, errno_str ? errno_str : "<no error string>");
                }
            }
            break;
#endif

        case 'a': // attach {pid|process_name}
            if (optarg && optarg[0])
                attach_target = optarg;
                break;

        case 'h':   /* fall-through is intentional */
        case '?':
            show_usage = true;
            break;
        }
    }

    if (show_usage || option_error)
    {
        display_usage(progname, subcommand);
        exit(option_error);
    }

    if (!LLDBServerUtilities::SetupLogging(log_file, log_channels, 0))
        return -1;

    Log *log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_VERBOSE));
    if (log)
    {
        log->Printf ("lldb-server launch");
        for (int i = 0; i < argc; i++)
        {
            log->Printf ("argv[%i] = '%s'", i, argv[i]);
        }
    }

    // Skip any options we consumed with getopt_long_only.
    argc -= optind;
    argv += optind;

    if (argc == 0)
    {
        display_usage(progname, subcommand);
        exit(255);
    }

    // Setup the platform that GDBRemoteCommunicationServerLLGS will use.
    lldb::PlatformSP platform_sp = setup_platform (platform_name);

    GDBRemoteCommunicationServerLLGS gdb_server (platform_sp, mainloop);

    const char *const host_and_port = argv[0];
    argc -= 1;
    argv += 1;

    // Any arguments left over are for the program that we need to launch. If there
    // are no arguments, then the GDB server will start up and wait for an 'A' packet
    // to launch a program, or a vAttach packet to attach to an existing process, unless
    // explicitly asked to attach with the --attach={pid|program_name} form.
    if (!attach_target.empty ())
        handle_attach (gdb_server, attach_target);
    else if (argc > 0)
        handle_launch (gdb_server, argc, argv);

    // Print version info.
    printf("%s-%s", LLGS_PROGRAM_NAME, LLGS_VERSION_STR);

    ConnectToRemote(mainloop, gdb_server, reverse_connect,
                    host_and_port, progname, subcommand,
                    named_pipe_path.c_str(), unnamed_pipe_fd);


    if (! gdb_server.IsConnected())
    {
        fprintf (stderr, "no connection information provided, unable to run\n");
        display_usage (progname, subcommand);
        return 1;
    }

    mainloop.Run();
    fprintf(stderr, "lldb-server exiting...\n");

    return 0;
}
