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

#include "CommandObjectExpression.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Expression/ClangExpressionVariable.h"
#include "lldb/Expression/ClangUserExpression.h"
#include "lldb/Expression/ClangFunction.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"

using namespace lldb;
using namespace lldb_private;

CommandObjectExpression::CommandOptions::CommandOptions () :
    OptionGroup()
{
}


CommandObjectExpression::CommandOptions::~CommandOptions ()
{
}

static OptionEnumValueElement g_description_verbosity_type[] =
{
    { eLanguageRuntimeDescriptionDisplayVerbosityCompact,      "compact",       "Only show the description string"},
    { eLanguageRuntimeDescriptionDisplayVerbosityFull,         "full",          "Show the full output, including persistent variable's name and type"},
    { 0, NULL, NULL }
};

OptionDefinition
CommandObjectExpression::CommandOptions::g_option_table[] =
{
    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads",        'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "Should we run all threads if the execution doesn't complete on one thread."},
    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "Ignore breakpoint hits while running expressions"},
    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout",            't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,  "Timeout value (in microseconds) for running the expression."},
    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error",    'u', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "Clean up program state if the expression causes a crash, or raises a signal.  Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."},
    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug",              'g', OptionParser::eNoArgument      , NULL, NULL, 0, eArgTypeNone,       "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."},
    { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, NULL, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity,        "How verbose should the output of this expression be, if the object description is asked for."},
};


uint32_t
CommandObjectExpression::CommandOptions::GetNumDefinitions ()
{
    return llvm::array_lengthof(g_option_table);
}

Error
CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
                                                         uint32_t option_idx,
                                                         const char *option_arg)
{
    Error error;

    const int short_option = g_option_table[option_idx].short_option;

    switch (short_option)
    {
      //case 'l':
      //if (language.SetLanguageFromCString (option_arg) == false)
      //{
      //    error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
      //}
      //break;

    case 'a':
        {
            bool success;
            bool result;
            result = Args::StringToBoolean(option_arg, true, &success);
            if (!success)
                error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
            else
                try_all_threads = result;
        }
        break;
        
    case 'i':
        {
            bool success;
            bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
            if (success)
                ignore_breakpoints = tmp_value;
            else
                error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
            break;
        }
    case 't':
        {
            bool success;
            uint32_t result;
            result = StringConvert::ToUInt32(option_arg, 0, 0, &success);
            if (success)
                timeout = result;
            else
                error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
        }
        break;
        
    case 'u':
        {
            bool success;
            bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
            if (success)
                unwind_on_error = tmp_value;
            else
                error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
            break;
        }
            
    case 'v':
        if (!option_arg)
        {
            m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
            break;
        }
        m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
        if (!error.Success())
            error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg);
        break;
    
    case 'g':
        debug = true;
        unwind_on_error = false;
        ignore_breakpoints = false;
        break;

    default:
        error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
        break;
    }

    return error;
}

void
CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
{
    Process *process = interpreter.GetExecutionContext().GetProcessPtr();
    if (process != NULL)
    {
        ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
        unwind_on_error    = process->GetUnwindOnErrorInExpressions();
    }
    else
    {
        ignore_breakpoints = true;
        unwind_on_error = true;
    }
    
    show_summary = true;
    try_all_threads = true;
    timeout = 0;
    debug = false;
    m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
}

const OptionDefinition*
CommandObjectExpression::CommandOptions::GetDefinitions ()
{
    return g_option_table;
}

CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
    CommandObjectRaw (interpreter,
                      "expression",
                      "Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
                      NULL,
                      eCommandProcessMustBePaused | eCommandTryTargetAPILock),
    IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
    m_option_group (interpreter),
    m_format_options (eFormatDefault),
    m_command_options (),
    m_expr_line_count (0),
    m_expr_lines ()
{
  SetHelpLong(
"Timeouts:\n\
    If the expression can be evaluated statically (without running code) then it will be.\n\
    Otherwise, by default the expression will run on the current thread with a short timeout:\n\
    currently .25 seconds.  If it doesn't return in that time, the evaluation will be interrupted\n\
    and resumed with all threads running.  You can use the -a option to disable retrying on all\n\
    threads.  You can use the -t option to set a shorter timeout.\n\
\n\
User defined variables:\n\
    You can define your own variables for convenience or to be used in subsequent expressions.\n\
    You define them the same way you would define variables in C.  If the first character of \n\
    your user defined variable is a $, then the variable's value will be available in future\n\
    expressions, otherwise it will just be available in the current expression.\n\
\n\
\n\
Continuing evaluation after a breakpoint:\n\
    If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once\n\
    you are done with your investigation, you can either remove the expression execution frames\n\
    from the stack with \"thread return -x\" or if you are still interested in the expression result\n\
    you can issue the \"continue\" command and the expression evaluation will complete and the\n\
    expression result will be available using the \"thread.completed-expression\" key in the thread\n\
    format.\n\
\n\
Examples: \n\
\n\
   expr my_struct->a = my_array[3] \n\
   expr -f bin -- (index * 8) + 5 \n\
   expr unsigned int $foo = 5\n\
   expr char c[] = \"foo\"; c[0]\n");

    CommandArgumentEntry arg;
    CommandArgumentData expression_arg;

    // Define the first (and only) variant of this arg.
    expression_arg.arg_type = eArgTypeExpression;
    expression_arg.arg_repetition = eArgRepeatPlain;

    // There is only one variant this argument could be; put it into the argument entry.
    arg.push_back (expression_arg);

    // Push the data for the first argument into the m_arguments vector.
    m_arguments.push_back (arg);
    
    // Add the "--format" and "--gdb-format"
    m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
    m_option_group.Append (&m_command_options);
    m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
    m_option_group.Finalize();
}

CommandObjectExpression::~CommandObjectExpression ()
{
}

Options *
CommandObjectExpression::GetOptions ()
{
    return &m_option_group;
}

bool
CommandObjectExpression::EvaluateExpression 
(
    const char *expr, 
    Stream *output_stream, 
    Stream *error_stream,
    CommandReturnObject *result
)
{
    // Don't use m_exe_ctx as this might be called asynchronously
    // after the command object DoExecute has finished when doing
    // multi-line expression that use an input reader...
    ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());

    Target *target = exe_ctx.GetTargetPtr();
    
    if (!target)
        target = GetDummyTarget();
    
    if (target)
    {
        lldb::ValueObjectSP result_valobj_sp;

        bool keep_in_memory = true;

        EvaluateExpressionOptions options;
        options.SetCoerceToId(m_varobj_options.use_objc);
        options.SetUnwindOnError(m_command_options.unwind_on_error);
        options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
        options.SetKeepInMemory(keep_in_memory);
        options.SetUseDynamic(m_varobj_options.use_dynamic);
        options.SetTryAllThreads(m_command_options.try_all_threads);
        options.SetDebug(m_command_options.debug);
        
        // If there is any chance we are going to stop and want to see
        // what went wrong with our expression, we should generate debug info
        if (!m_command_options.ignore_breakpoints ||
            !m_command_options.unwind_on_error)
            options.SetGenerateDebugInfo(true);
        
        if (m_command_options.timeout > 0)
            options.SetTimeoutUsec(m_command_options.timeout);
        else
            options.SetTimeoutUsec(0);

        target->EvaluateExpression(expr, exe_ctx.GetFramePtr(),
                                   result_valobj_sp, options);

        if (result_valobj_sp)
        {
            Format format = m_format_options.GetFormat();

            if (result_valobj_sp->GetError().Success())
            {
                if (format != eFormatVoid)
                {
                    if (format != eFormatDefault)
                        result_valobj_sp->SetFormat (format);

                    DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));

                    result_valobj_sp->Dump(*output_stream,options);
                    
                    if (result)
                        result->SetStatus (eReturnStatusSuccessFinishResult);
                }
            }
            else
            {
                if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
                {
                    if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
                    {
                        error_stream->PutCString("(void)\n");
                    }
                    
                    if (result)
                        result->SetStatus (eReturnStatusSuccessFinishResult);
                }
                else
                {
                    const char *error_cstr = result_valobj_sp->GetError().AsCString();
                    if (error_cstr && error_cstr[0])
                    {
                        const size_t error_cstr_len = strlen (error_cstr);
                        const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
                        if (strstr(error_cstr, "error:") != error_cstr)
                            error_stream->PutCString ("error: ");
                        error_stream->Write(error_cstr, error_cstr_len);
                        if (!ends_with_newline)
                            error_stream->EOL();
                    }
                    else
                    {
                        error_stream->PutCString ("error: unknown error\n");
                    }
                    
                    if (result)
                        result->SetStatus (eReturnStatusFailed);
                }
            }
        }
    }
    else
    {
        error_stream->Printf ("error: invalid execution context for expression\n");
        return false;
    }
        
    return true;
}

void
CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
{
    io_handler.SetIsDone(true);
//    StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
//    StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
    StreamFileSP output_sp(io_handler.GetOutputStreamFile());
    StreamFileSP error_sp(io_handler.GetErrorStreamFile());

    EvaluateExpression (line.c_str(),
                        output_sp.get(),
                        error_sp.get());
    if (output_sp)
        output_sp->Flush();
    if (error_sp)
        error_sp->Flush();
}

LineStatus
CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
                                                StringList &lines,
                                                uint32_t line_idx,
                                                Error &error)
{
    if (line_idx == UINT32_MAX)
    {
        // Remove the last line from "lines" so it doesn't appear
        // in our final expression
        lines.PopBack();
        error.Clear();
        return LineStatus::Done;
    }
    else if (line_idx + 1 == lines.GetSize())
    {
        // The last line was edited, if this line is empty, then we are done
        // getting our multiple lines.
        if (lines[line_idx].empty())
            return LineStatus::Done;
    }
    return LineStatus::Success;
}

void
CommandObjectExpression::GetMultilineExpression ()
{
    m_expr_lines.clear();
    m_expr_line_count = 0;
    
    Debugger &debugger = GetCommandInterpreter().GetDebugger();
    bool color_prompt = debugger.GetUseColor();
    const bool multiple_lines = true; // Get multiple lines
    IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
                                                      IOHandler::Type::Expression,
                                                      "lldb-expr",      // Name of input reader for history
                                                      NULL,             // No prompt
                                                      NULL,             // Continuation prompt
                                                      multiple_lines,
                                                      color_prompt,
                                                      1,                // Show line numbers starting at 1
                                                      *this));
    
    StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
    if (output_sp)
    {
        output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
        output_sp->Flush();
    }
    debugger.PushIOHandler(io_handler_sp);
}

bool
CommandObjectExpression::DoExecute
(
    const char *command,
    CommandReturnObject &result
)
{
    m_option_group.NotifyOptionParsingStarting();

    const char * expr = NULL;

    if (command[0] == '\0')
    {
        GetMultilineExpression ();
        return result.Succeeded();
    }

    if (command[0] == '-')
    {
        // We have some options and these options MUST end with --.
        const char *end_options = NULL;
        const char *s = command;
        while (s && s[0])
        {
            end_options = ::strstr (s, "--");
            if (end_options)
            {
                end_options += 2; // Get past the "--"
                if (::isspace (end_options[0]))
                {
                    expr = end_options;
                    while (::isspace (*expr))
                        ++expr;
                    break;
                }
            }
            s = end_options;
        }

        if (end_options)
        {
            Args args (llvm::StringRef(command, end_options - command));
            if (!ParseOptions (args, result))
                return false;
            
            Error error (m_option_group.NotifyOptionParsingFinished());
            if (error.Fail())
            {
                result.AppendError (error.AsCString());
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
            
            // No expression following options
            if (expr == NULL || expr[0] == '\0')
            {
                GetMultilineExpression ();
                return result.Succeeded();
            }
        }
    }

    if (expr == NULL)
        expr = command;
    
    if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
        return true;

    result.SetStatus (eReturnStatusFailed);
    return false;
}

