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

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/REPL.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/AnsiTerminal.h"

using namespace lldb_private;

REPL::REPL(LLVMCastKind kind, Target &target) :
    m_target(target),
    m_kind(kind)
{
    // Make sure all option values have sane defaults
    Debugger &debugger = m_target.GetDebugger();
    CommandInterpreter &ci = debugger.GetCommandInterpreter();
    m_format_options.OptionParsingStarting(ci);
    m_varobj_options.OptionParsingStarting(ci);
    m_command_options.OptionParsingStarting(ci);
    
    // Default certain settings for REPL regardless of the global settings.
    m_command_options.unwind_on_error = false;
    m_command_options.ignore_breakpoints = false;
    m_command_options.debug = false;
}

REPL::~REPL() = default;

lldb::REPLSP
REPL::Create(Error &err, lldb::LanguageType language, Debugger *debugger, Target *target, const char *repl_options)
{
    uint32_t idx = 0;
    lldb::REPLSP ret;
    
    while (REPLCreateInstance create_instance = PluginManager::GetREPLCreateCallbackAtIndex(idx++))
    {
        ret = (*create_instance)(err, language, debugger, target, repl_options);
        if (ret)
        {
            break;
        }
    }
    
    return ret;
}

std::string
REPL::GetSourcePath()
{
    ConstString file_basename = GetSourceFileBasename();
    
    FileSpec tmpdir_file_spec;
    if (HostInfo::GetLLDBPath (lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
    {
        tmpdir_file_spec.GetFilename().SetCString(file_basename.AsCString());
        m_repl_source_path = tmpdir_file_spec.GetPath();
    }
    else
    {
        tmpdir_file_spec = FileSpec("/tmp", false);
        tmpdir_file_spec.AppendPathComponent(file_basename.AsCString());
    }
    
    return tmpdir_file_spec.GetPath();
}

lldb::IOHandlerSP
REPL::GetIOHandler()
{
    if (!m_io_handler_sp)
    {
        Debugger &debugger = m_target.GetDebugger();
        m_io_handler_sp.reset (new IOHandlerEditline (debugger,
                                                      IOHandler::Type::REPL,
                                                      "lldb-repl",     // Name of input reader for history
                                                      "> ",             // prompt
                                                      ". ",             // Continuation prompt
                                                      true,             // Multi-line
                                                      true,             // The REPL prompt is always colored
                                                      1,                // Line number
                                                      *this));
        
        // Don't exit if CTRL+C is pressed
        static_cast<IOHandlerEditline *>(m_io_handler_sp.get())->SetInterruptExits(false);
        
        if (m_io_handler_sp->GetIsInteractive() && m_io_handler_sp->GetIsRealTerminal())
        {
            m_indent_str.assign (debugger.GetTabSize(), ' ');
            m_enable_auto_indent = debugger.GetAutoIndent();
        }
        else
        {
            m_indent_str.clear();
            m_enable_auto_indent = false;
        }
        
    }
    return m_io_handler_sp;
}

void
REPL::IOHandlerActivated (IOHandler &io_handler)
{
    lldb::ProcessSP process_sp = m_target.GetProcessSP();
    if (process_sp && process_sp->IsAlive())
        return;
    lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFile());
    error_sp->Printf("REPL requires a running target process.\n");
    io_handler.SetIsDone(true);
}

bool
REPL::IOHandlerInterrupt (IOHandler &io_handler)
{
    return false;
}

void
REPL::IOHandlerInputInterrupted (IOHandler &io_handler,
                                 std::string &line)
{
}

const char *
REPL::IOHandlerGetFixIndentationCharacters()
{
    return (m_enable_auto_indent ? GetAutoIndentCharacters() : nullptr);
}

ConstString
REPL::IOHandlerGetControlSequence (char ch)
{
    if (ch == 'd')
        return ConstString(":quit\n");
    return ConstString();
}

const char *
REPL::IOHandlerGetCommandPrefix ()
{
    return ":";
}

const char *
REPL::IOHandlerGetHelpPrologue ()
{
    return "\nThe REPL (Read-Eval-Print-Loop) acts like an interpreter.  "
    "Valid statements, expressions, and declarations are immediately compiled and executed.\n\n"
    "The complete set of LLDB debugging commands are also available as described below.  Commands "
    "must be prefixed with a colon at the REPL prompt (:quit for example.)  Typing just a colon "
    "followed by return will switch to the LLDB prompt.\n\n";
}

bool
REPL::IOHandlerIsInputComplete (IOHandler &io_handler,
                                StringList &lines)
{
    // Check for meta command
    const size_t num_lines = lines.GetSize();
    if (num_lines == 1)
    {
        const char *first_line = lines.GetStringAtIndex(0);
        if (first_line[0] == ':')
            return true; // Meta command is a single line where that starts with ':'
    }
    
    // Check if REPL input is done
    std::string source_string (lines.CopyList());
    return SourceIsComplete(source_string);
}

int
REPL::CalculateActualIndentation (const StringList &lines)
{
    std::string last_line = lines[lines.GetSize() - 1];

    int actual_indent = 0;
    for (char &ch : last_line)
    {
        if (ch != ' ') break;
        ++actual_indent;
    }
    
    return actual_indent;
}

int
REPL::IOHandlerFixIndentation (IOHandler &io_handler,
                               const StringList &lines,
                               int cursor_position)
{
    if (!m_enable_auto_indent) return 0;
    
    if (!lines.GetSize())
    {
        return 0;
    }
    
    int tab_size = io_handler.GetDebugger().GetTabSize();

    lldb::offset_t desired_indent = GetDesiredIndentation(lines,
                                                          cursor_position,
                                                          tab_size);
    
    int actual_indent = REPL::CalculateActualIndentation(lines);
    
    if (desired_indent == LLDB_INVALID_OFFSET)
        return 0;
    
    return (int)desired_indent - actual_indent;
}

void
REPL::IOHandlerInputComplete (IOHandler &io_handler, std::string &code)
{
    lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFile());
    lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFile());
    bool extra_line = false;
    bool did_quit = false;
    
    if (code.empty())
    {
        m_code.AppendString("");
        static_cast<IOHandlerEditline &>(io_handler).SetBaseLineNumber(m_code.GetSize()+1);
    }
    else
    {
        Debugger &debugger = m_target.GetDebugger();
        CommandInterpreter &ci = debugger.GetCommandInterpreter();
        extra_line = ci.GetSpaceReplPrompts();
        
        ExecutionContext exe_ctx (m_target.GetProcessSP()->GetThreadList().GetSelectedThread()->GetSelectedFrame().get());
        
        lldb::ProcessSP process_sp(exe_ctx.GetProcessSP());
        
        if (code[0] == ':')
        {
            // Meta command
            // Strip the ':'
            code.erase(0, 1);
            if (Args::StripSpaces (code))
            {
                // "lldb" was followed by arguments, so just execute the command dump the results
                
                // Turn off prompt on quit in case the user types ":quit"
                const bool saved_prompt_on_quit = ci.GetPromptOnQuit();
                if (saved_prompt_on_quit)
                    ci.SetPromptOnQuit(false);
                
                // Execute the command
                CommandReturnObject result;
                result.SetImmediateOutputStream(output_sp);
                result.SetImmediateErrorStream(error_sp);
                ci.HandleCommand(code.c_str(), eLazyBoolNo, result);
                
                if (saved_prompt_on_quit)
                    ci.SetPromptOnQuit(true);
                
                if (result.GetStatus() == lldb::eReturnStatusQuit)
                {
                    did_quit = true;
                    io_handler.SetIsDone(true);
                    if (debugger.CheckTopIOHandlerTypes(IOHandler::Type::REPL, IOHandler::Type::CommandInterpreter))
                    {
                        // We typed "quit" or an alias to quit so we need to check if the
                        // command interpreter is above us and tell it that it is done as well
                        // so we don't drop back into the command interpreter if we have already
                        // quit
                        lldb::IOHandlerSP io_handler_sp (ci.GetIOHandler());
                        if (io_handler_sp)
                            io_handler_sp->SetIsDone(true);
                    }
                }
            }
            else
            {
                // ":" was followed by no arguments, so push the LLDB command prompt
                if (debugger.CheckTopIOHandlerTypes(IOHandler::Type::REPL, IOHandler::Type::CommandInterpreter))
                {
                    // If the user wants to get back to the command interpreter and the
                    // command interpreter is what launched the REPL, then just let the
                    // REPL exit and fall back to the command interpreter.
                    io_handler.SetIsDone(true);
                }
                else
                {
                    // The REPL wasn't launched the by the command interpreter, it is the
                    // base IOHandler, so we need to get the command interpreter and
                    lldb::IOHandlerSP io_handler_sp (ci.GetIOHandler());
                    if (io_handler_sp)
                    {
                        io_handler_sp->SetIsDone(false);
                        debugger.PushIOHandler(ci.GetIOHandler());
                    }
                }
            }
        }
        else
        {
            // Unwind any expression we might have been running in case our REPL
            // expression crashed and the user was looking around
            if (m_dedicated_repl_mode)
            {
                Thread *thread = exe_ctx.GetThreadPtr();
                if (thread && thread->UnwindInnermostExpression().Success())
                {
                    thread->SetSelectedFrameByIndex(0, false);
                    exe_ctx.SetFrameSP(thread->GetSelectedFrame());
                }
            }
            
            const bool colorize_err = error_sp->GetFile().GetIsTerminalWithColors();
            
            EvaluateExpressionOptions expr_options;
            expr_options.SetCoerceToId(m_varobj_options.use_objc);
            expr_options.SetUnwindOnError(m_command_options.unwind_on_error);
            expr_options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
            expr_options.SetKeepInMemory(true);
            expr_options.SetUseDynamic(m_varobj_options.use_dynamic);
            expr_options.SetTryAllThreads(m_command_options.try_all_threads);
            expr_options.SetGenerateDebugInfo(true);
            expr_options.SetREPLEnabled (true);
            expr_options.SetColorizeErrors(colorize_err);
            expr_options.SetPoundLine(m_repl_source_path.c_str(), m_code.GetSize() + 1);
            if (m_command_options.timeout > 0)
                expr_options.SetTimeoutUsec(m_command_options.timeout);
            else
                expr_options.SetTimeoutUsec(0);
            
            expr_options.SetLanguage(GetLanguage());
            
            PersistentExpressionState *persistent_state = m_target.GetPersistentExpressionStateForLanguage(GetLanguage());
            
            const size_t var_count_before = persistent_state->GetSize();
            
            const char *expr_prefix = nullptr;
            lldb::ValueObjectSP result_valobj_sp;
            Error error;
            lldb::ModuleSP jit_module_sp;
            lldb::ExpressionResults execution_results = UserExpression::Evaluate (exe_ctx,
                                                                                  expr_options,
                                                                                  code.c_str(),
                                                                                  expr_prefix,
                                                                                  result_valobj_sp,
                                                                                  error,
                                                                                  0, // Line offset
                                                                                  &jit_module_sp);
            
            //CommandInterpreter &ci = debugger.GetCommandInterpreter();
            
            if (process_sp && process_sp->IsAlive())
            {
                bool add_to_code = true;
                bool handled = false;
                if (result_valobj_sp)
                {
                    lldb::Format format = m_format_options.GetFormat();
                    
                    if (result_valobj_sp->GetError().Success())
                    {
                        handled |= PrintOneVariable(debugger, output_sp, result_valobj_sp);
                    }
                    else if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult)
                    {
                        if (format != lldb::eFormatVoid && debugger.GetNotifyVoid())
                        {
                            error_sp->PutCString("(void)\n");
                            handled = true;
                        }
                    }
                }
                
                if (debugger.GetPrintDecls())
                {
                    for (size_t vi = var_count_before, ve = persistent_state->GetSize();
                         vi != ve;
                         ++vi)
                    {
                        lldb::ExpressionVariableSP persistent_var_sp = persistent_state->GetVariableAtIndex(vi);
                        lldb::ValueObjectSP valobj_sp = persistent_var_sp->GetValueObject();
                        
                        PrintOneVariable(debugger, output_sp, valobj_sp, persistent_var_sp.get());
                    }
                }

                if (!handled)
                {
                    bool useColors = error_sp->GetFile().GetIsTerminalWithColors();
                    switch (execution_results)
                    {
                        case lldb::eExpressionSetupError:
                        case lldb::eExpressionParseError:
                            add_to_code = false;
                            // Fall through
                        case lldb::eExpressionDiscarded:
                            error_sp->Printf("%s\n", error.AsCString());
                            break;
                            
                        case lldb::eExpressionCompleted:
                            break;
                        case lldb::eExpressionInterrupted:
                            if (useColors) {
                                error_sp->Printf(ANSI_ESCAPE1(ANSI_FG_COLOR_RED));
                                error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_BOLD));
                            }
                            error_sp->Printf("Execution interrupted. ");
                            if (useColors) error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_NORMAL));
                            error_sp->Printf("Enter code to recover and continue.\nEnter LLDB commands to investigate (type :help for assistance.)\n");
                            break;
                            
                        case lldb::eExpressionHitBreakpoint:
                            // Breakpoint was hit, drop into LLDB command interpreter
                            if (useColors) {
                                error_sp->Printf(ANSI_ESCAPE1(ANSI_FG_COLOR_RED));
                                error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_BOLD));
                            }
                            output_sp->Printf("Execution stopped at breakpoint.  ");
                            if (useColors) error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_NORMAL));
                            output_sp->Printf("Enter LLDB commands to investigate (type help for assistance.)\n");
                        {
                            lldb::IOHandlerSP io_handler_sp (ci.GetIOHandler());
                            if (io_handler_sp)
                            {
                                io_handler_sp->SetIsDone(false);
                                debugger.PushIOHandler(ci.GetIOHandler());
                            }
                        }
                            break;
                            
                        case lldb::eExpressionTimedOut:
                            error_sp->Printf("error: timeout\n");
                            if (error.AsCString())
                                error_sp->Printf("error: %s\n", error.AsCString());
                            break;
                        case lldb::eExpressionResultUnavailable:
                            // Shoulnd't happen???
                            error_sp->Printf("error: could not fetch result -- %s\n", error.AsCString());
                            break;
                        case lldb::eExpressionStoppedForDebug:
                            // Shoulnd't happen???
                            error_sp->Printf("error: stopped for debug -- %s\n", error.AsCString());
                            break;
                    }
                }
                
                if (add_to_code)
                {
                    const uint32_t new_default_line = m_code.GetSize() + 1;
                    
                    m_code.SplitIntoLines(code);
                    
                    // Update our code on disk
                    if (!m_repl_source_path.empty())
                    {
                        lldb_private::File file (m_repl_source_path.c_str(),
                                                 File::eOpenOptionWrite | File::eOpenOptionTruncate | File::eOpenOptionCanCreate,
                                                 lldb::eFilePermissionsFileDefault);
                        std::string code (m_code.CopyList());
                        code.append(1, '\n');
                        size_t bytes_written = code.size();
                        file.Write(code.c_str(), bytes_written);
                        file.Close();
                        
                        // Now set the default file and line to the REPL source file
                        m_target.GetSourceManager().SetDefaultFileAndLine(FileSpec(m_repl_source_path.c_str(), false), new_default_line);
                    }
                    static_cast<IOHandlerEditline &>(io_handler).SetBaseLineNumber(m_code.GetSize()+1);
                }
                if (extra_line)
                {
                    fprintf(output_sp->GetFile().GetStream(), "\n");
                }
            }
        }
        
        // Don't complain about the REPL process going away if we are in the process of quitting.
        if (!did_quit && (!process_sp || !process_sp->IsAlive()))
        {
            error_sp->Printf("error: REPL process is no longer alive, exiting REPL\n");
            io_handler.SetIsDone(true);
        }
    }
}

int
REPL::IOHandlerComplete (IOHandler &io_handler,
                         const char *current_line,
                         const char *cursor,
                         const char *last_char,
                         int skip_first_n_matches,
                         int max_matches,
                         StringList &matches)
{
    matches.Clear();
    
    llvm::StringRef line (current_line, cursor - current_line);
    
    // Complete an LLDB command if the first character is a colon...
    if (!line.empty() && line[0] == ':')
    {
        Debugger &debugger = m_target.GetDebugger();
        
        // auto complete LLDB commands
        const char *lldb_current_line = line.substr(1).data();
        return debugger.GetCommandInterpreter().HandleCompletion (lldb_current_line,
                                                                  cursor,
                                                                  last_char,
                                                                  skip_first_n_matches,
                                                                  max_matches,
                                                                  matches);
    }
    
    // Strip spaces from the line and see if we had only spaces
    line = line.ltrim();
    if (line.empty())
    {
        // Only spaces on this line, so just indent
        matches.AppendString(m_indent_str);
        return 1;
    }
    
    std::string current_code;
    current_code.append(m_code.CopyList());
    
    IOHandlerEditline &editline = static_cast<IOHandlerEditline &>(io_handler);
    const StringList *current_lines = editline.GetCurrentLines();
    if (current_lines)
    {
        const uint32_t current_line_idx = editline.GetCurrentLineIndex();
        
        if (current_line_idx < current_lines->GetSize())
        {
            for (uint32_t i=0; i<current_line_idx; ++i)
            {
                const char *line_cstr = current_lines->GetStringAtIndex(i);
                if (line_cstr)
                {
                    current_code.append("\n");
                    current_code.append (line_cstr);
                }
            }
        }
    }
    
    if (cursor > current_line)
    {
        current_code.append("\n");
        current_code.append(current_line, cursor - current_line);
    }
    
    return CompleteCode(current_code, matches);
}

bool
QuitCommandOverrideCallback(void *baton, const char **argv)
{
    Target *target = (Target *)baton;
    lldb::ProcessSP process_sp (target->GetProcessSP());
    if (process_sp)
    {
        process_sp->Destroy(false);
        process_sp->GetTarget().GetDebugger().ClearIOHandlers();
    }
    return false;
}

Error
REPL::RunLoop ()
{
    Error error;
    
    error = DoInitialization();
    m_repl_source_path = GetSourcePath();
    
    if (!error.Success())
        return error;
    
    Debugger &debugger = m_target.GetDebugger();
    
    lldb::IOHandlerSP io_handler_sp (GetIOHandler());
    
    FileSpec save_default_file;
    uint32_t save_default_line = 0;
    
    if (!m_repl_source_path.empty())
    {
        // Save the current default file and line
        m_target.GetSourceManager().GetDefaultFileAndLine(save_default_file, save_default_line);
    }
    
    debugger.PushIOHandler(io_handler_sp);
    
    // Check if we are in dedicated REPL mode where LLDB was start with the "--repl" option
    // from the command line. Currently we know this by checking if the debugger already
    // has a IOHandler thread.
    if (!debugger.HasIOHandlerThread())
    {
        // The debugger doesn't have an existing IOHandler thread, so this must be
        // dedicated REPL mode...
        m_dedicated_repl_mode = true;
        debugger.StartIOHandlerThread();
        std::string command_name_str ("quit");
        CommandObject *cmd_obj = debugger.GetCommandInterpreter().GetCommandObjectForCommand(command_name_str);
        if (cmd_obj)
        {
            assert(command_name_str.empty());
            cmd_obj->SetOverrideCallback (QuitCommandOverrideCallback, &m_target);
        }
    }
    
    // Wait for the REPL command interpreter to get popped
    io_handler_sp->WaitForPop();
    
    if (m_dedicated_repl_mode)
    {
        // If we were in dedicated REPL mode we would have started the
        // IOHandler thread, and we should kill our process
        lldb::ProcessSP process_sp = m_target.GetProcessSP();
        if (process_sp && process_sp->IsAlive())
            process_sp->Destroy(false);
        
        // Wait for the IO handler thread to exit (TODO: don't do this if the IO handler thread already exists...)
        debugger.JoinIOHandlerThread();
    }
    
    // Restore the default file and line
    if (save_default_file && save_default_line != 0)
        m_target.GetSourceManager().SetDefaultFileAndLine(save_default_file, save_default_line);
    return error;
}
