//===-- 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,  false,  "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,  false,  "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,  false,  "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_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; SPACES, which is
// a string that is output_max_columns long, containing spaces; and 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, char *spaces, const char *text, int output_max_columns)
{
    int len = strlen (text);
    std::string text_string (text);
    std::string spaces_string (spaces);

    // 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", spaces_string.substr (0, indent).c_str(), 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", spaces_string.substr(0, indent).c_str(), 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";
    char spaces[screen_width+1];
    uint32_t i;
    
    for (i = 0; i < screen_width; ++i)
      spaces[i] = ' ';
    spaces[i] = '\n';

    std::string spaces_string (spaces);

    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 (int 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", spaces_string.substr(0, indent_level).c_str(), 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 ", spaces_string.substr(0, indent_level).c_str(), 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 ", spaces_string.substr(0, indent_level).c_str(), 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, spaces, 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",
             spaces_string.substr(0, indent_level).c_str(), name);
}

void
BuildGetOptTable (lldb::OptionDefinition *expanded_option_table, struct option **getopt_table, int 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;

}

SBError
ParseOptions (Driver::OptionData &data, int argc, const char **argv)
{
    SBError error;
    std::string option_string;
    struct option *long_options = NULL;
    int num_options;

    for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options);

    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, (char * const *) argv, option_string.c_str(), long_options, &long_options_index);

        if (val == -1)
            break;
        else if (val == '?')
        {
            data.m_print_help = true;
            error.SetErrorStringWithFormat ("unknown or ambiguous option");
            break;
        }
        else if (val == 0)
            continue;
        else
        {
            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)
            {
                error = Driver::SetOptionValue (long_options_index,
                                                long_options[long_options_index].has_arg == no_argument ? NULL : optarg,
                                                data);
            }
            else
            {
                error.SetErrorStringWithFormat ("invalid option with value %i", val);
            }
            if (error.Fail())
                break;
        }
    }

    return error;
}

Driver::OptionData::OptionData () :
    m_filename(),
    m_script_lang (lldb::eScriptLanguageDefault),
    m_source_command_files (),
    m_debug_mode (false),
    m_print_help (false),
    m_print_version (false)

{
}

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;
}

SBError
Driver::SetOptionValue (int option_idx, const char *option_arg, Driver::OptionData &option_data)
{
    SBError error;
    const char short_option = (char) g_options[option_idx].short_option;

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

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

        case 'c':
            option_data.m_crash_log = option_arg;
            break;

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

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

        case 'l':
            option_data.m_script_lang = SBDebugger::GetScriptingLanguage (option_arg);
            break;

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

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

        default:
            option_data.m_print_help = true;
            error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
            break;
    }

    return error;
}

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.

bool
Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, FILE *err_fh)
{
    bool valid = true;

    ResetOptionValues ();

    SBCommandReturnObject result;

    SBError error = ParseOptions (m_option_data, argc, argv);
    if (error.Fail())
    {
        const char *error_cstr = error.GetCString ();
        if (error_cstr)
            ::fprintf (err_fh, "error: %s\n", error_cstr);
        valid = false;
    }
    
    // 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
        {
            ::fprintf (err_fh, "error: don't provide a file both on in the -f option and as an argument.");
            valid = false;
        }

    }
    else if (optind < argc - 1)
    {
        // Trailing extra arguments...
        ::fprintf (err_fh, "error: trailing extra arguments - only one the filename is allowed.");
        valid = false;
        
    }
    
    if (!valid || m_option_data.m_print_help)
    {
        ShowUsage (out_fh, g_options, m_option_data);
        valid = false;
    }
    else if (m_option_data.m_print_version)
    {
        ::fprintf (out_fh, "%s\n", SBDebugger::GetVersionString());
        valid = false;
    }
    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 valid;
}

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 = SBDebugger::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 = SBDebugger::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(SBDebugger::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(),
                                              SBDebugger::StateAsCString (event_state));
                m_io_channel_ap->OutWrite(message, message_len);
            }
            break;

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

        case eStateExited:
            SBDebugger::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 ();
                SBDebugger::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 (SBDebugger::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 (SBDebugger::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 = SBDebugger::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);

    SBDebugger::SetErrorFileHandle (stderr, false);
    SBDebugger::SetOutputFileHandle (stdout, false);
    SBDebugger::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 = SBDebugger::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);
        SBDebugger::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 (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);
    }
    
    SBDebugger::PushInputReader (m_editline_reader);

    SBListener listener(SBDebugger::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 (SBDebugger::GetErrorFileHandle());
                result.PutOutput (SBDebugger::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), "source '%s'", command_file);
                    SBDebugger::GetCommandInterpreter().HandleCommand (command_string, result, false);
                    if (GetDebugMode())
                    {
                        result.PutError (SBDebugger::GetErrorFileHandle());
                        result.PutOutput (SBDebugger::GetOutputFileHandle());
                    }
                }
            }

            if (!m_option_data.m_filename.empty())
            {
                char arch_name[64];
                if (SBDebugger::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());

                SBDebugger::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(SBDebugger::GetErrorFileHandle());
                result.PutOutput(SBDebugger::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 (SBDebugger::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)
            {
                SBEvent event;
                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 = SBDebugger::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]");

    // Do a little setup on the debugger before we get going
    SBDebugger::SetAsync(true);
    Driver driver;

    bool valid_args = driver.ParseArgs (argc, argv, stdout, stderr);
    if (valid_args)
    {
        driver.MainLoop ();
    }

    SBDebugger::Terminate();
    return 0;
}
