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

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// CommandObjectRegexCommand constructor
//----------------------------------------------------------------------
CommandObjectRegexCommand::CommandObjectRegexCommand
(
    CommandInterpreter &interpreter,
    const char *name,
    const char *help,
    const char *syntax,
    uint32_t max_matches,
    uint32_t completion_type_mask,
    bool is_removable
) :
    CommandObjectRaw (interpreter, name, help, syntax),
    m_max_matches (max_matches),
    m_completion_type_mask (completion_type_mask),
    m_entries (),
    m_is_removable (is_removable)
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
CommandObjectRegexCommand::~CommandObjectRegexCommand()
{
}


bool
CommandObjectRegexCommand::DoExecute
(
    const char *command,
    CommandReturnObject &result
)
{
    if (command)
    {
        EntryCollection::const_iterator pos, end = m_entries.end();
        for (pos = m_entries.begin(); pos != end; ++pos)
        {
            RegularExpression::Match regex_match(m_max_matches);

            if (pos->regex.Execute (command, &regex_match))
            {
                std::string new_command(pos->command);
                std::string match_str;
                char percent_var[8];
                size_t idx, percent_var_idx;
                for (uint32_t match_idx=1; match_idx <= m_max_matches; ++match_idx)
                {
                    if (regex_match.GetMatchAtIndex (command, match_idx, match_str))
                    {
                        const int percent_var_len = ::snprintf (percent_var, sizeof(percent_var), "%%%u", match_idx);
                        for (idx = 0; (percent_var_idx = new_command.find(percent_var, idx)) != std::string::npos; )
                        {
                            new_command.erase(percent_var_idx, percent_var_len);
                            new_command.insert(percent_var_idx, match_str);
                            idx += percent_var_idx + match_str.size();
                        }
                    }
                }
                // Interpret the new command and return this as the result!
                if (m_interpreter.GetExpandRegexAliases())
                    result.GetOutputStream().Printf("%s\n", new_command.c_str());
                // Pass in true for "no context switching".  The command that called us should have set up the context
                // appropriately, we shouldn't have to redo that.
                return m_interpreter.HandleCommand(new_command.c_str(), eLazyBoolCalculate, result, nullptr, true, true);
            }
        }
        result.SetStatus(eReturnStatusFailed);
        if (GetSyntax() != nullptr)
            result.AppendError (GetSyntax());
        else
            result.AppendErrorWithFormat ("Command contents '%s' failed to match any regular expression in the '%s' regex command.\n",
                                          command,
                                          m_cmd_name.c_str());
        return false;
    }
    result.AppendError("empty command passed to regular expression command");
    result.SetStatus(eReturnStatusFailed);
    return false;
}


bool
CommandObjectRegexCommand::AddRegexCommand (const char *re_cstr, const char *command_cstr)
{
    m_entries.resize(m_entries.size() + 1);
    // Only add the regular expression if it compiles
    if (m_entries.back().regex.Compile (re_cstr))
    {
        m_entries.back().command.assign (command_cstr);
        return true;
    }
    // The regex didn't compile...
    m_entries.pop_back();
    return false;
}

int
CommandObjectRegexCommand::HandleCompletion (Args &input,
                                             int &cursor_index,
                                             int &cursor_char_position,
                                             int match_start_point,
                                             int max_return_elements,
                                             bool &word_complete,
                                             StringList &matches)
{
    if (m_completion_type_mask)
    {
        std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
                                                             m_completion_type_mask,
                                                             completion_str.c_str(),
                                                             match_start_point,
                                                             max_return_elements,
                                                             nullptr,
                                                             word_complete,
                                                             matches);
        return matches.GetSize();
    }
    else
    {
        matches.Clear();
        word_complete = false;
    }
    return 0;
}
