//===-- 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 "Plugins/ExpressionParser/Clang/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/Language.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 | LLDB_OPT_SET_2, false, "language",           'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,   "Specifies the Language to use when parsing the expression.  If not set the target.language setting is used." },
    { 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':
        language = Language::GetLanguageTypeFromString (option_arg);
        if (language == eLanguageTypeUnknown)
            error.SetErrorStringWithFormat ("unknown language type: '%s' for expression", 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;
    language = eLanguageTypeUnknown;
    m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
}

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

CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
    CommandObjectRaw (interpreter,
                      "expression",
                      "Evaluate an 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(
R"(
Timeouts:

)" "    If the expression can be evaluated statically (without running code) then it will be.  \
Otherwise, by default the expression will run on the current thread with a short timeout: \
currently .25 seconds.  If it doesn't return in that time, the evaluation will be interrupted \
and resumed with all threads running.  You can use the -a option to disable retrying on all \
threads.  You can use the -t option to set a shorter timeout." R"(

User defined variables:

)" "    You can define your own variables for convenience or to be used in subsequent expressions.  \
You define them the same way you would define variables in C.  If the first character of \
your user defined variable is a $, then the variable's value will be available in future \
expressions, otherwise it will just be available in the current expression." R"(

Continuing evaluation after a breakpoint:

)" "    If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \
you are done with your investigation, you can either remove the expression execution frames \
from the stack with \"thread return -x\" or if you are still interested in the expression result \
you can issue the \"continue\" command and the expression evaluation will complete and the \
expression result will be available using the \"thread.completed-expression\" key in the thread \
format." R"(

Examples:

    expr my_struct->a = my_array[3]
    expr -f bin -- (index * 8) + 5
    expr unsigned int $foo = 5
    expr char c[] = \"foo\"; c[0])"
    );

    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 the language was not specified, set it from target's properties
        if (m_command_options.language != eLanguageTypeUnknown)
            options.SetLanguage(m_command_options.language);
        else
            options.SetLanguage(target->GetLanguage());

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

