//===-- 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/Interpreter/Args.h"
#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/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 = Args::StringToUInt32(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 = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
    
    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();
    const bool multiple_lines = true; // Get multiple lines
    IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
                                                      "lldb-expr",      // Name of input reader for history
                                                      NULL,             // No prompt
                                                      multiple_lines,
                                                      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 (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;
}

