//===-- 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 "lldb/lldb-python.h"

#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,
                      eFlagProcessMustBePaused | eFlagTryTargetAPILock),
    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;
}

