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

#include "Driver.h"

#include <getopt.h>
#include <libgen.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <fcntl.h>

#include <string>

#include "IOChannel.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBCommunication.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBHostOS.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBSourceManager.h"
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBProcess.h"

using namespace lldb;

static void reset_stdin_termios ();
static struct termios g_old_stdin_termios;

// In the Driver::MainLoop, we change the terminal settings.  This function is
// added as an atexit handler to make sure we clean them up.
static void
reset_stdin_termios ()
{
    ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
}

static lldb::OptionDefinition g_options[] =
{
    { LLDB_OPT_SET_1,  true, "help", 'h',  no_argument,        NULL,  NULL,  NULL,
        "Prints out the usage information for the LLDB debugger." },

    { LLDB_OPT_SET_2,  true, "version", 'v',  no_argument,        NULL,  NULL,  NULL,
        "Prints out the current version number of the LLDB debugger." },

    { LLDB_OPT_SET_3,  true, "arch", 'a',  required_argument,  NULL,  NULL,  "<architecture>",
        "Tells the debugger to use the specified architecture when starting and running the program.  <architecture> must be one of the architectures for which the program was compiled." },

    { LLDB_OPT_SET_3 | LLDB_OPT_SET_4,  false,  "script-language",'l',  required_argument,  NULL,  NULL,  "<scripting-language>",
        "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default.  Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl.  Currently only the Python extensions have been implemented." },

    { LLDB_OPT_SET_3 | LLDB_OPT_SET_4,  false,  "debug",          'd',  no_argument,        NULL,  NULL,  NULL,
        "Tells the debugger to print out extra information for debugging itself." },

    { LLDB_OPT_SET_3 | LLDB_OPT_SET_4,  false,  "source",         's',  required_argument,  NULL,  NULL,  "<file>",
        "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." },

    { LLDB_OPT_SET_3,  true,  "file",           'f',  required_argument,  NULL,  NULL,  "<filename>",
        "Tells the debugger to use the file <filename> as the program to be debugged." },

//    { LLDB_OPT_SET_4,  true,  "crash-log",      'c',  required_argument,  NULL,  NULL,  "<file>",
//        "Load executable images from a crash log for symbolication." },

    { 0, false, NULL, 0, 0, NULL, NULL,  NULL, NULL }
};


Driver::Driver () :
    SBBroadcaster ("Driver"),
    m_debugger (SBDebugger::Create()),
    m_editline_pty (),
    m_editline_slave_fh (NULL),
    m_editline_reader (),
    m_io_channel_ap (),
    m_option_data (),
    m_waiting_for_command (false)
{
}

Driver::~Driver ()
{
}

void
Driver::CloseIOChannelFile ()
{
    // Write and End of File sequence to the file descriptor to ensure any
    // read functions can exit.
    char eof_str[] = "\x04";
    ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));

    m_editline_pty.CloseMasterFileDescriptor();

    if (m_editline_slave_fh)
    {
        ::fclose (m_editline_slave_fh);
        m_editline_slave_fh = NULL;
    }
}

// This function takes INDENT, which tells how many spaces to output at the front
// of each line; TEXT, which is the text that is to be output. It outputs the 
// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the 
// front of each line.  It breaks lines on spaces, tabs or newlines, shortening 
// the line if necessary to not break in the middle of a word. It assumes that 
// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.

void
OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
{
    int len = strlen (text);
    std::string text_string (text);

    // Force indentation to be reasonable.
    if (indent >= output_max_columns)
        indent = 0;

    // Will it all fit on one line?

    if (len + indent < output_max_columns)
        // Output as a single line
        fprintf (out, "%*s%s\n", indent, "", text);
    else
    {
        // We need to break it up into multiple lines.
        int text_width = output_max_columns - indent - 1;
        int start = 0;
        int end = start;
        int final_end = len;
        int sub_len;

        while (end < final_end)
        {
              // Dont start the 'text' on a space, since we're already outputting the indentation.
              while ((start < final_end) && (text[start] == ' '))
                  start++;

              end = start + text_width;
              if (end > final_end)
                  end = final_end;
              else
              {
                  // If we're not at the end of the text, make sure we break the line on white space.
                  while (end > start
                         && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
                      end--;
              }
              sub_len = end - start;
              std::string substring = text_string.substr (start, sub_len);
              fprintf (out, "%*s%s\n", indent, "", substring.c_str());
              start = end + 1;
        }
    }
}

void
ShowUsage (FILE *out, lldb::OptionDefinition *option_table, Driver::OptionData data)
{
    uint32_t screen_width = 80;
    uint32_t indent_level = 0;
    const char *name = "lldb";
    
    fprintf (out, "\nUsage:\n\n");

    indent_level += 2;


    // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
    //                                                   <cmd> [options-for-level-1]
    //                                                   etc.

    uint32_t num_options;
    uint32_t num_option_sets = 0;
    
    for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
    {
        uint32_t this_usage_mask = option_table[num_options].usage_mask;
        if (this_usage_mask == LLDB_OPT_SET_ALL)
        {
            if (num_option_sets == 0)
                num_option_sets = 1;
        }
        else
        {
            for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
            {
                if (this_usage_mask & 1 << j)
                {
                    if (num_option_sets <= j)
                        num_option_sets = j + 1;
                }
            }
        }
    }

    for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
    {
        uint32_t opt_set_mask;
        
        opt_set_mask = 1 << opt_set;
        
        if (opt_set > 0)
            fprintf (out, "\n");
        fprintf (out, "%*s%s", indent_level, "", name);
        
        for (uint32_t i = 0; i < num_options; ++i)
        {
            if (option_table[i].usage_mask & opt_set_mask)
            {
                if (option_table[i].required)
                {
                    if (option_table[i].option_has_arg == required_argument)
                        fprintf (out, " -%c %s", option_table[i].short_option, option_table[i].argument_name);
                    else if (option_table[i].option_has_arg == optional_argument)
                        fprintf (out, " -%c [%s]", option_table[i].short_option, option_table[i].argument_name);
                    else
                        fprintf (out, " -%c", option_table[i].short_option);
                }
                else
                {
                    if (option_table[i].option_has_arg == required_argument)
                        fprintf (out, " [-%c %s]", option_table[i].short_option, option_table[i].argument_name);
                    else if (option_table[i].option_has_arg == optional_argument)
                        fprintf (out, " [-%c [%s]]", option_table[i].short_option, option_table[i].argument_name);
                    else
                        fprintf (out, " [-%c]", option_table[i].short_option);
                }
            }
        }
    }

    fprintf (out, "\n\n");

    // Now print out all the detailed information about the various options:  long form, short form and help text:
    //   -- long_name <argument>
    //   - short <argument>
    //   help text

    // This variable is used to keep track of which options' info we've printed out, because some options can be in
    // more than one usage level, but we only want to print the long form of its information once.

    Driver::OptionData::OptionSet options_seen;
    Driver::OptionData::OptionSet::iterator pos;

    indent_level += 5;

    for (uint32_t i = 0; i < num_options; ++i)
    {
        // Only print this option if we haven't already seen it.
        pos = options_seen.find (option_table[i].short_option);
        if (pos == options_seen.end())
        {
            options_seen.insert (option_table[i].short_option);
            fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
            if (option_table[i].argument_name != NULL)
                fprintf (out, "%s", option_table[i].argument_name);
            fprintf (out, "\n");
            fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
            if (option_table[i].argument_name != NULL)
                fprintf (out, "%s", option_table[i].argument_name);
            fprintf (out, "\n");
            indent_level += 5;
            OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
            indent_level -= 5;
            fprintf (out, "\n");
        }
    }

    indent_level -= 5;

    fprintf (out, "\n%*s('%s <filename>' also works, to specify the file to be debugged.)\n\n",
             indent_level, "", name);
}

void
BuildGetOptTable (lldb::OptionDefinition *expanded_option_table, struct option **getopt_table, uint32_t num_options)
{
    if (num_options == 0)
        return;

    uint32_t i;
    uint32_t j;
    std::bitset<256> option_seen;

    for (i = 0, j = 0; i < num_options; ++i)
    {
        char short_opt = expanded_option_table[i].short_option;
        
        if (option_seen.test(short_opt) == false)
        {
            (*getopt_table)[j].name    = expanded_option_table[i].long_option;
            (*getopt_table)[j].has_arg = expanded_option_table[i].option_has_arg;
            (*getopt_table)[j].flag    = NULL;
            (*getopt_table)[j].val     = expanded_option_table[i].short_option;
            option_seen.set(short_opt);
            ++j;
        }
    }

    (*getopt_table)[j].name    = NULL;
    (*getopt_table)[j].has_arg = 0;
    (*getopt_table)[j].flag    = NULL;
    (*getopt_table)[j].val     = 0;

}

Driver::OptionData::OptionData () :
    m_filename(),
    m_script_lang (lldb::eScriptLanguageDefault),
    m_crash_log (),
    m_source_command_files (),
    m_debug_mode (false),
    m_print_version (false),
    m_print_help (false),
    m_seen_options()
{
}

Driver::OptionData::~OptionData ()
{
}

void
Driver::OptionData::Clear ()
{
    m_filename.clear ();
    m_script_lang = lldb::eScriptLanguageDefault;
    m_source_command_files.clear ();
    m_debug_mode = false;
    m_print_help = false;
    m_print_version = false;
}

void
Driver::ResetOptionValues ()
{
    m_option_data.Clear ();
}

const char *
Driver::GetFilename() const
{
    if (m_option_data.m_filename.empty())
        return NULL;
    return m_option_data.m_filename.c_str();
}

const char *
Driver::GetCrashLogFilename() const
{
    if (m_option_data.m_crash_log.empty())
        return NULL;
    return m_option_data.m_crash_log.c_str();
}

lldb::ScriptLanguage
Driver::GetScriptLanguage() const
{
    return m_option_data.m_script_lang;
}

size_t
Driver::GetNumSourceCommandFiles () const
{
    return m_option_data.m_source_command_files.size();
}

const char *
Driver::GetSourceCommandFileAtIndex (uint32_t idx) const
{
    if (idx < m_option_data.m_source_command_files.size())
        return m_option_data.m_source_command_files[idx].c_str();
    return NULL;
}

bool
Driver::GetDebugMode() const
{
    return m_option_data.m_debug_mode;
}


// Check the arguments that were passed to this program to make sure they are valid and to get their
// argument values (if any).  Return a boolean value indicating whether or not to start up the full
// debugger (i.e. the Command Interpreter) or not.  Return FALSE if the arguments were invalid OR
// if the user only wanted help or version information.

SBError
Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit)
{
    ResetOptionValues ();

    SBCommandReturnObject result;

    SBError error;
    std::string option_string;
    struct option *long_options = NULL;
    uint32_t num_options;

    for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
        /* Do Nothing. */;

    if (num_options == 0)
    {
        if (argc > 1)
            error.SetErrorStringWithFormat ("invalid number of options");
        return error;
    }

    long_options = (struct option *) malloc ((num_options + 1) * sizeof (struct option));

    BuildGetOptTable (g_options, &long_options, num_options);

    if (long_options == NULL)
    {
        error.SetErrorStringWithFormat ("invalid long options");
        return error;
    }

    // Build the option_string argument for call to getopt_long.

    for (int i = 0; long_options[i].name != NULL; ++i)
    {
        if (long_options[i].flag == NULL)
        {
            option_string.push_back ((char) long_options[i].val);
            switch (long_options[i].has_arg)
            {
                default:
                case no_argument:
                    break;
                case required_argument:
                    option_string.push_back (':');
                    break;
                case optional_argument:
                    option_string.append ("::");
                    break;
            }
        }
    }

    // Prepare for & make calls to getopt_long.
#if __GLIBC__
    optind = 0;
#else
    optreset = 1;
    optind = 1;
#endif
    int val;
    while (1)
    {
        int long_options_index = -1;
        val = ::getopt_long (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);

        if (val == -1)
            break;
        else if (val == '?')
        {
            m_option_data.m_print_help = true;
            error.SetErrorStringWithFormat ("unknown or ambiguous option");
            break;
        }
        else if (val == 0)
            continue;
        else
        {
            m_option_data.m_seen_options.insert ((char) val);
            if (long_options_index == -1)
            {
                for (int i = 0;
                     long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
                     ++i)
                {
                    if (long_options[i].val == val)
                    {
                        long_options_index = i;
                        break;
                    }
                }
            }

            if (long_options_index >= 0)
            {
                const char short_option = (char) g_options[long_options_index].short_option;

                switch (short_option)
                {
                    case 'h':
                        m_option_data.m_print_help = true;
                        break;

                    case 'v':
                        m_option_data.m_print_version = true;
                        break;

                    case 'c':
                        m_option_data.m_crash_log = optarg;
                        break;

                    case 'f':
                        {
                            SBFileSpec file(optarg);
                            if (file.Exists())
                                m_option_data.m_filename = optarg;
                            else
                                error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
                        }
                        break;

                    case 'a':
                        if (!m_debugger.SetDefaultArchitecture (optarg))
                            error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
                        break;

                    case 'l':
                        m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
                        break;

                    case 'd':
                        m_option_data.m_debug_mode = true;
                        break;

                    case 's':
                        {
                            SBFileSpec file(optarg);
                            if (file.Exists())
                                m_option_data.m_source_command_files.push_back (optarg);
                            else
                                error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
                        }
                        break;

                    default:
                        m_option_data.m_print_help = true;
                        error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
                        break;
                }
            }
            else
            {
                error.SetErrorStringWithFormat ("invalid option with value %i", val);
            }
            if (error.Fail())
                return error;
        }
    }
    
    // If there is a trailing argument, it is the filename.
    if (optind == argc - 1)
    {
        if (m_option_data.m_filename.empty())
        {
            m_option_data.m_filename = argv[optind];
        }
        else
        {
            error.SetErrorStringWithFormat ("error: don't provide a file both on in the -f option and as an argument.");
        }

    }
    else if (optind < argc - 1)
    {
        // Trailing extra arguments...
        error.SetErrorStringWithFormat ("error: trailing extra arguments - only one the filename is allowed.");
    }
    
    if (error.Fail() || m_option_data.m_print_help)
    {
        ShowUsage (out_fh, g_options, m_option_data);
    }
    else if (m_option_data.m_print_version)
    {
        ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
        exit = true;
    }
    else if (! m_option_data.m_crash_log.empty())
    {
        // Handle crash log stuff here.
    }
    else
    {
        // All other combinations are valid; do nothing more here.
    }

    return error;
}

void
Driver::GetProcessSTDOUT ()
{
    //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
    char stdio_buffer[1024];
    size_t len;
    while ((len = m_debugger.GetCurrentTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
        m_io_channel_ap->OutWrite (stdio_buffer, len);
}

void
Driver::GetProcessSTDERR ()
{
    //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
    char stdio_buffer[1024];
    size_t len;
    while ((len = m_debugger.GetCurrentTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
        m_io_channel_ap->ErrWrite (stdio_buffer, len);
}

void
Driver::UpdateCurrentThread ()
{
    using namespace lldb;
    SBProcess process(m_debugger.GetCurrentTarget().GetProcess());
    if (process.IsValid())
    {
        SBThread curr_thread (process.GetCurrentThread());
        SBThread thread;
        StopReason curr_thread_stop_reason = eStopReasonInvalid;
        curr_thread_stop_reason = curr_thread.GetStopReason();

        if (!curr_thread.IsValid() ||
            curr_thread_stop_reason == eStopReasonInvalid ||
            curr_thread_stop_reason == eStopReasonNone)
        {
            // Prefer a thread that has just completed its plan over another thread as current thread.
            SBThread plan_thread;
            SBThread other_thread;
            const size_t num_threads = process.GetNumThreads();
            size_t i;
            for (i = 0; i < num_threads; ++i)
            {
                thread = process.GetThreadAtIndex(i);
                StopReason thread_stop_reason = thread.GetStopReason();
                switch (thread_stop_reason)
                {
                default:
                case eStopReasonInvalid:
                case eStopReasonNone:
                    break;

                case eStopReasonTrace:
                case eStopReasonBreakpoint:
                case eStopReasonWatchpoint:
                case eStopReasonSignal:
                case eStopReasonException:
                    if (!other_thread.IsValid())
                        other_thread = thread;
                    break;
                case eStopReasonPlanComplete:
                    if (!plan_thread.IsValid())
                        plan_thread = thread;
                    break;
                }
            }
            if (plan_thread.IsValid())
                process.SetCurrentThread (plan_thread);
            else if (other_thread.IsValid())
                process.SetCurrentThread (other_thread);
            else
            {
                if (curr_thread.IsValid())
                    thread = curr_thread;
                else
                    thread = process.GetThreadAtIndex(0);

                if (thread.IsValid())
                    process.SetCurrentThread (thread);
            }
        }
    }
}


// This function handles events that were broadcast by the process.
void
Driver::HandleProcessEvent (const SBEvent &event)
{
    using namespace lldb;
    const uint32_t event_type = event.GetType();

    if (event_type & SBProcess::eBroadcastBitSTDOUT)
    {
        // The process has stdout available, get it and write it out to the
        // appropriate place.
        GetProcessSTDOUT ();
    }
    else if (event_type & SBProcess::eBroadcastBitSTDERR)
    {
        // The process has stderr available, get it and write it out to the
        // appropriate place.
        GetProcessSTDERR ();
    }
    else if (event_type & SBProcess::eBroadcastBitStateChanged)
    {
        // Drain all stout and stderr so we don't see any output come after
        // we print our prompts
        GetProcessSTDOUT ();
        GetProcessSTDERR ();

        // Something changed in the process;  get the event and report the process's current status and location to
        // the user.
        StateType event_state = SBProcess::GetStateFromEvent (event);
        if (event_state == eStateInvalid)
            return;

        SBProcess process (SBProcess::GetProcessFromEvent (event));
        assert (process.IsValid());

        switch (event_state)
        {
        case eStateInvalid:
        case eStateUnloaded:
        case eStateAttaching:
        case eStateLaunching:
        case eStateStepping:
        case eStateDetached:
            {
                char message[1024];
                int message_len = ::snprintf (message, sizeof(message), "Process %d %s\n", process.GetProcessID(),
                                              m_debugger.StateAsCString (event_state));
                m_io_channel_ap->OutWrite(message, message_len);
            }
            break;

        case eStateRunning:
            // Don't be chatty when we run...
            break;

        case eStateExited:
            m_debugger.HandleCommand("process status");
            m_io_channel_ap->RefreshPrompt();
            break;

        case eStateStopped:
        case eStateCrashed:
        case eStateSuspended:
            // Make sure the program hasn't been auto-restarted:
            if (SBProcess::GetRestartedFromEvent (event))
            {
                // FIXME: Do we want to report this, or would that just be annoyingly chatty?
                char message[1024];
                int message_len = ::snprintf (message, sizeof(message), "Process %d stopped and was programmatically restarted.\n",
                                              process.GetProcessID());
                m_io_channel_ap->OutWrite(message, message_len);
            }
            else
            {
                UpdateCurrentThread ();
                m_debugger.HandleCommand("process status");
                m_io_channel_ap->RefreshPrompt();
            }
            break;
        }
    }
}

//  This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).

bool
Driver::HandleIOEvent (const SBEvent &event)
{
    bool quit = false;

    const uint32_t event_type = event.GetType();

    if (event_type & IOChannel::eBroadcastBitHasUserInput)
    {
        // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
        // handling.

        const char *command_string = SBEvent::GetCStringFromEvent(event);
        if (command_string == NULL)
            command_string = "";
        SBCommandReturnObject result;
        if (m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true) != lldb::eReturnStatusQuit)
        {
            m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize());
            m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize());
        }
        // We are done getting and running our command, we can now clear the
        // m_waiting_for_command so we can get another one.
        m_waiting_for_command = false;

        // If our editline input reader is active, it means another input reader
        // got pushed onto the input reader and caused us to become deactivated.
        // When the input reader above us gets popped, we will get re-activated
        // and our prompt will refresh in our callback
        if (m_editline_reader.IsActive())
        {
            ReadyForCommand ();
        }
    }
    else if (event_type & IOChannel::eBroadcastBitUserInterrupt)
    {
        // This is here to handle control-c interrupts from the user.  It has not yet really been implemented.
        // TO BE DONE:  PROPERLY HANDLE CONTROL-C FROM USER
        //m_io_channel_ap->CancelInput();
        // Anything else?  Send Interrupt to process?
    }
    else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
             (event_type & IOChannel::eBroadcastBitThreadDidExit))
    {
        // If the IOChannel thread is trying to go away, then it is definitely
        // time to end the debugging session.
        quit = true;
    }

    return quit;
}


//struct CrashImageInfo
//{
//    std::string path;
//    VMRange text_range;
//    UUID uuid;
//};
//
//void
//Driver::ParseCrashLog (const char *crash_log)
//{
//    printf("Parsing crash log: %s\n", crash_log);
//
//    char image_path[PATH_MAX];
//    std::vector<CrashImageInfo> crash_infos;
//    if (crash_log && crash_log[0])
//    {
//        FileSpec crash_log_file (crash_log);
//        STLStringArray crash_log_lines;
//        if (crash_log_file.ReadFileLines (crash_log_lines))
//        {
//            const size_t num_crash_log_lines = crash_log_lines.size();
//            size_t i;
//            for (i=0; i<num_crash_log_lines; ++i)
//            {
//                const char *line = crash_log_lines[i].c_str();
//                if (strstr (line, "Code Type:"))
//                {
//                    char arch_string[256];
//                    if (sscanf(line, "%s", arch_string))
//                    {
//                        if (strcmp(arch_string, "X86-64"))
//                            lldb::GetDefaultArchitecture ().SetArch ("x86_64");
//                        else if (strcmp(arch_string, "X86"))
//                            lldb::GetDefaultArchitecture ().SetArch ("i386");
//                        else
//                        {
//                            ArchSpec arch(arch_string);
//                            if (arch.IsValid ())
//                                lldb::GetDefaultArchitecture () = arch;
//                            else
//                                fprintf(stderr, "Unrecognized architecture: %s\n", arch_string);
//                        }
//                    }
//                }
//                else
//                if (strstr(line, "Path:"))
//                {
//                    const char *p = line + strlen("Path:");
//                    while (isspace(*p))
//                        ++p;
//
//                    m_option_data.m_filename.assign (p);
//                }
//                else
//                if (strstr(line, "Binary Images:"))
//                {
//                    while (++i < num_crash_log_lines)
//                    {
//                        if (crash_log_lines[i].empty())
//                            break;
//
//                        line = crash_log_lines[i].c_str();
//                        uint64_t text_start_addr;
//                        uint64_t text_end_addr;
//                        char uuid_cstr[64];
//                        int bytes_consumed_before_uuid = 0;
//                        int bytes_consumed_after_uuid = 0;
//
//                        int items_parsed = ::sscanf (line,
//                                                     "%llx - %llx %*s %*s %*s %n%s %n",
//                                                     &text_start_addr,
//                                                     &text_end_addr,
//                                                     &bytes_consumed_before_uuid,
//                                                     uuid_cstr,
//                                                     &bytes_consumed_after_uuid);
//
//                        if (items_parsed == 3)
//                        {
//
//                            CrashImageInfo info;
//                            info.text_range.SetBaseAddress(text_start_addr);
//                            info.text_range.SetEndAddress(text_end_addr);
//
//                            if (uuid_cstr[0] == '<')
//                            {
//                                if (info.uuid.SetfromCString (&uuid_cstr[1]) == 0)
//                                    info.uuid.Clear();
//
//                                ::strncpy (image_path, line + bytes_consumed_after_uuid, sizeof(image_path));
//                            }
//                            else
//                            {
//                                ::strncpy (image_path, line + bytes_consumed_before_uuid, sizeof(image_path));
//                            }
//
//                            info.path = image_path;
//
//                            crash_infos.push_back (info);
//
//                            info.uuid.GetAsCString(uuid_cstr, sizeof(uuid_cstr));
//
//                            printf("0x%16.16llx - 0x%16.16llx <%s> %s\n",
//                                   text_start_addr,
//                                   text_end_addr,
//                                   uuid_cstr,
//                                   image_path);
//                        }
//                    }
//                }
//            }
//        }
//
//        if (crash_infos.size())
//        {
//            SBTarget target (m_debugger.CreateTarget (crash_infos.front().path.c_str(),
//                                                      lldb::GetDefaultArchitecture().AsCString (),
//                                                      false));
//            if (target.IsValid())
//            {
//
//            }
//        }
//    }
//}
//

void
Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len)
{
    Driver *driver = (Driver*)baton;
    driver->GetFromMaster ((const char *)src, src_len);
}

void
Driver::GetFromMaster (const char *src, size_t src_len)
{
    // Echo the characters back to the Debugger's stdout, that way if you
    // type characters while a command is running, you'll see what you've typed.
    FILE *out_fh = m_debugger.GetOutputFileHandle();
    if (out_fh)
        ::fwrite (src, 1, src_len, out_fh);
}

size_t
Driver::EditLineInputReaderCallback 
(
    void *baton, 
    SBInputReader *reader, 
    InputReaderAction notification,
    const char *bytes, 
    size_t bytes_len
)
{
    Driver *driver = (Driver *)baton;

    switch (notification)
    {
    case eInputReaderActivate:
        break;

    case eInputReaderReactivate:
        driver->ReadyForCommand();
        break;

    case eInputReaderDeactivate:
        break;

    case eInputReaderGotToken:
        write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
        break;
        
    case eInputReaderDone:
        break;
    }
    return bytes_len;
}

void
Driver::MainLoop ()
{
    char error_str[1024];
    if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
    {
        ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str);
        exit(1);
    }
    else
    {
        const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str));
        if (driver_slave_name == NULL)
        {
            ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str);
            exit(2);
        }
        else
        {
            m_editline_slave_fh = ::fopen (driver_slave_name, "r+");
            if (m_editline_slave_fh == NULL)
            {
                SBError error;
                error.SetErrorToErrno();
                ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s",
                           error.GetCString());
                exit(3);
            }

            ::setbuf (m_editline_slave_fh, NULL);
        }
    }


   // struct termios stdin_termios;

    if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
        atexit (reset_stdin_termios);

    ::setbuf (stdin, NULL);
    ::setbuf (stdout, NULL);

    m_debugger.SetErrorFileHandle (stderr, false);
    m_debugger.SetOutputFileHandle (stdout, false);
    m_debugger.SetInputFileHandle (stdin, true);

    // You have to drain anything that comes to the master side of the PTY.  master_out_comm is
    // for that purpose.  The reason you need to do this is a curious reason...  editline will echo
    // characters to the PTY when it gets characters while el_gets is not running, and then when
    // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks
    // if there are unconsumed characters in the out buffer.
    // However, you don't need to do anything with the characters, since editline will dump these
    // unconsumed characters after printing the prompt again in el_gets.

    SBCommunication master_out_comm("driver.editline");
    master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false);
    master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this);

    if (master_out_comm.ReadThreadStart () == false)
    {
        ::fprintf (stderr, "error: failed to start master out read thread");
        exit(5);
    }

//    const char *crash_log = GetCrashLogFilename();
//    if (crash_log)
//    {
//        ParseCrashLog (crash_log);
//    }
//
    SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();

    m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, stdout, stderr, this));

    struct winsize window_size;
    if (isatty (STDIN_FILENO)
        && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
    {
        char buffer[25];

        sprintf (buffer, "set term-width %d", window_size.ws_col);
        m_debugger.HandleCommand ((const char *) buffer);
    }

    // Since input can be redirected by the debugger, we must insert our editline
    // input reader in the queue so we know when our reader should be active
    // and so we can receive bytes only when we are supposed to.
    SBError err (m_editline_reader.Initialize (m_debugger, 
                                               Driver::EditLineInputReaderCallback, // callback
                                               this,                              // baton
                                               eInputReaderGranularityByte,       // token_size
                                               NULL,                              // end token - NULL means never done
                                               NULL,                              // prompt - taken care of elsewhere
                                               false));                           // echo input - don't need Debugger 
                                                                                  // to do this, we handle it elsewhere
    
    if (err.Fail())
    {
        ::fprintf (stderr, "error: %s", err.GetCString());
        exit (6);
    }
    
    m_debugger.PushInputReader (m_editline_reader);

    SBListener listener(m_debugger.GetListener());
    if (listener.IsValid())
    {

        listener.StartListeningForEvents (*m_io_channel_ap,
                                          IOChannel::eBroadcastBitHasUserInput |
                                          IOChannel::eBroadcastBitUserInterrupt |
                                          IOChannel::eBroadcastBitThreadShouldExit |
                                          IOChannel::eBroadcastBitThreadDidStart |
                                          IOChannel::eBroadcastBitThreadDidExit);

        if (m_io_channel_ap->Start ())
        {
            bool iochannel_thread_exited = false;

            listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
                                              SBCommandInterpreter::eBroadcastBitQuitCommandReceived);

            // Before we handle any options from the command line, we parse the
            // .lldbinit file in the user's home directory.
            SBCommandReturnObject result;
            sb_interpreter.SourceInitFileInHomeDirectory(result);
            if (GetDebugMode())
            {
                result.PutError (m_debugger.GetErrorFileHandle());
                result.PutOutput (m_debugger.GetOutputFileHandle());
            }

            // Now we handle options we got from the command line
            char command_string[PATH_MAX * 2];
            const size_t num_source_command_files = GetNumSourceCommandFiles();
            if (num_source_command_files > 0)
            {
                for (size_t i=0; i < num_source_command_files; ++i)
                {
                    const char *command_file = GetSourceCommandFileAtIndex(i);
                    ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file);
                    m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false);
                    if (GetDebugMode())
                    {
                        result.PutError (m_debugger.GetErrorFileHandle());
                        result.PutOutput (m_debugger.GetOutputFileHandle());
                    }
                }
            }

            if (!m_option_data.m_filename.empty())
            {
                char arch_name[64];
                if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
                    ::snprintf (command_string, sizeof (command_string), "file --arch=%s '%s'", arch_name,
                                m_option_data.m_filename.c_str());
                else
                    ::snprintf (command_string, sizeof(command_string), "file '%s'", m_option_data.m_filename.c_str());

                m_debugger.HandleCommand (command_string);
            }

            // Now that all option parsing is done, we try and parse the .lldbinit
            // file in the current working directory
            sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
            if (GetDebugMode())
            {
                result.PutError(m_debugger.GetErrorFileHandle());
                result.PutOutput(m_debugger.GetOutputFileHandle());
            }

            SBEvent event;

            // Make sure the IO channel is started up before we try to tell it we
            // are ready for input
            listener.WaitForEventForBroadcasterWithType (UINT32_MAX, 
                                                         *m_io_channel_ap,
                                                         IOChannel::eBroadcastBitThreadDidStart, 
                                                         event);
            
            ReadyForCommand ();

            bool done = false;
            while (!done)
            {
                listener.WaitForEvent (UINT32_MAX, event);
                if (event.IsValid())
                {
                    if (event.GetBroadcaster().IsValid())
                    {
                        uint32_t event_type = event.GetType();
                        if (event.BroadcasterMatchesRef (*m_io_channel_ap))
                        {
                            if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
                                (event_type & IOChannel::eBroadcastBitThreadDidExit))
                            {
                                done = true;
                                if (event_type & IOChannel::eBroadcastBitThreadDidExit)
                                    iochannel_thread_exited = true;
                                break;
                            }
                            else
                                done = HandleIOEvent (event);
                        }
                        else if (event.BroadcasterMatchesRef (m_debugger.GetCurrentTarget().GetProcess().GetBroadcaster()))
                        {
                            HandleProcessEvent (event);
                        }
                        else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
                        {
                            if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
                                done = true;
                        }
                    }
                }
            }

            reset_stdin_termios ();

            CloseIOChannelFile ();

            if (!iochannel_thread_exited)
            {
                event.Clear();
                listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
                                                             IOChannel::eBroadcastBitThreadDidExit,
                                                             event);
                if (!event.IsValid())
                {
                    // Send end EOF to the driver file descriptor
                    m_io_channel_ap->Stop();
                }
            }

            SBProcess process = m_debugger.GetCurrentTarget().GetProcess();
            if (process.IsValid())
                process.Destroy();
        }
    }
}


void
Driver::ReadyForCommand ()
{
    if (m_waiting_for_command == false)
    {
        m_waiting_for_command = true;
        BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true);
    }
}


int
main (int argc, char const *argv[])
{
    SBDebugger::Initialize();
    
    SBHostOS::ThreadCreated ("[main]");

    // Create a scope for driver so that the driver object will destroy itself
    // before SBDebugger::Terminate() is called.
    {
        Driver driver;

        bool exit = false;
        SBError error (driver.ParseArgs (argc, argv, stdout, exit));
        if (error.Fail())
        {
            const char *error_cstr = error.GetCString ();
            if (error_cstr)
                ::fprintf (stderr, "error: %s\n", error_cstr);
        }
        else if (!exit)
        {
            driver.MainLoop ();
        }
    }

    SBDebugger::Terminate();
    return 0;
}
