//===-- CommandObjectMultiword.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/Interpreter/CommandObjectMultiword.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandReturnObject.h"

using namespace lldb;
using namespace lldb_private;

//-------------------------------------------------------------------------
// CommandObjectMultiword
//-------------------------------------------------------------------------

CommandObjectMultiword::CommandObjectMultiword
(
    CommandInterpreter &interpreter,
    const char *name,
    const char *help,
    const char *syntax,
    uint32_t flags
) :
    CommandObject (interpreter, name, help, syntax, flags),
    m_can_be_removed(false)
{
}

CommandObjectMultiword::~CommandObjectMultiword ()
{
}

CommandObjectSP
CommandObjectMultiword::GetSubcommandSP (const char *sub_cmd, StringList *matches)
{
    CommandObjectSP return_cmd_sp;
    CommandObject::CommandMap::iterator pos;

    if (!m_subcommand_dict.empty())
    {
        pos = m_subcommand_dict.find (sub_cmd);
        if (pos != m_subcommand_dict.end()) {
            // An exact match; append the sub_cmd to the 'matches' string list.
            if (matches)
                matches->AppendString(sub_cmd);
            return_cmd_sp = pos->second;
        }
        else
        {

            StringList local_matches;
            if (matches == NULL)
                matches = &local_matches;
            int num_matches = CommandObject::AddNamesMatchingPartialString (m_subcommand_dict, sub_cmd, *matches);

            if (num_matches == 1)
            {
                // Cleaner, but slightly less efficient would be to call back into this function, since I now
                // know I have an exact match...

                sub_cmd = matches->GetStringAtIndex(0);
                pos = m_subcommand_dict.find(sub_cmd);
                if (pos != m_subcommand_dict.end())
                    return_cmd_sp = pos->second;
            }
        }
    }
    return return_cmd_sp;
}

CommandObject *
CommandObjectMultiword::GetSubcommandObject (const char *sub_cmd, StringList *matches)
{
    return GetSubcommandSP(sub_cmd, matches).get();
}

bool
CommandObjectMultiword::LoadSubCommand 
(
    const char *name,
    const CommandObjectSP& cmd_obj
)
{
    if (cmd_obj.get())
        assert((&GetCommandInterpreter() == &cmd_obj->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter");
    
    CommandMap::iterator pos;
    bool success = true;

    pos = m_subcommand_dict.find(name);
    if (pos == m_subcommand_dict.end())
    {
        m_subcommand_dict[name] = cmd_obj;
    }
    else
        success = false;

    return success;
}

bool
CommandObjectMultiword::Execute(const char *args_string, CommandReturnObject &result)
{
    Args args (args_string);
    const size_t argc = args.GetArgumentCount();
    if (argc == 0)
    {
        this->CommandObject::GenerateHelpText (result);
    }
    else
    {
        const char *sub_command = args.GetArgumentAtIndex (0);

        if (sub_command)
        {
            if (::strcasecmp (sub_command, "help") == 0)
            {
                this->CommandObject::GenerateHelpText (result);
            }
            else if (!m_subcommand_dict.empty())
            {
                StringList matches;
                CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches);
                if (sub_cmd_obj != NULL)
                {
                    // Now call CommandObject::Execute to process and options in 'rest_of_line'.  From there
                    // the command-specific version of Execute will be called, with the processed arguments.

                    args.Shift();

                    sub_cmd_obj->Execute (args_string, result);
                }
                else
                {
                    std::string error_msg;
                    const size_t num_subcmd_matches = matches.GetSize();
                    if (num_subcmd_matches > 0)
                        error_msg.assign ("ambiguous command ");
                    else
                        error_msg.assign ("invalid command ");

                    error_msg.append ("'");
                    error_msg.append (GetCommandName());
                    error_msg.append (" ");
                    error_msg.append (sub_command);
                    error_msg.append ("'.");

                    if (num_subcmd_matches > 0)
                    {
                        error_msg.append (" Possible completions:");
                        for (size_t i = 0; i < num_subcmd_matches; i++)
                        {
                            error_msg.append ("\n\t");
                            error_msg.append (matches.GetStringAtIndex (i));
                        }
                    }
                    error_msg.append ("\n");
                    result.AppendRawError (error_msg.c_str());
                    result.SetStatus (eReturnStatusFailed);
                }
            }
            else
            {
                result.AppendErrorWithFormat ("'%s' does not have any subcommands.\n", GetCommandName());
                result.SetStatus (eReturnStatusFailed);
            }
        }
    }

    return result.Succeeded();
}

void
CommandObjectMultiword::GenerateHelpText (Stream &output_stream)
{
    // First time through here, generate the help text for the object and
    // push it to the return result object as well

    output_stream.PutCString ("The following subcommands are supported:\n\n");

    CommandMap::iterator pos;
    uint32_t max_len = m_interpreter.FindLongestCommandWord (m_subcommand_dict);

    if (max_len)
        max_len += 4; // Indent the output by 4 spaces.

    for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos)
    {
        std::string indented_command ("    ");
        indented_command.append (pos->first);
        if (pos->second->WantsRawCommandString ())
        {
            std::string help_text (pos->second->GetHelp());
            help_text.append ("  This command takes 'raw' input (no need to quote stuff).");
            m_interpreter.OutputFormattedHelpText (output_stream,
                                                   indented_command.c_str(),
                                                   "--",
                                                   help_text.c_str(),
                                                   max_len);
        }
        else
            m_interpreter.OutputFormattedHelpText (output_stream, 
                                                   indented_command.c_str(),
                                                   "--", 
                                                   pos->second->GetHelp(), 
                                                   max_len);
    }

    output_stream.PutCString ("\nFor more help on any particular subcommand, type 'help <command> <subcommand>'.\n");
}

int
CommandObjectMultiword::HandleCompletion
(
    Args &input,
    int &cursor_index,
    int &cursor_char_position,
    int match_start_point,
    int max_return_elements,
    bool &word_complete,
    StringList &matches
)
{
    // Any of the command matches will provide a complete word, otherwise the individual
    // completers will override this.
    word_complete = true;
    
    const char *arg0 = input.GetArgumentAtIndex(0);
    if (cursor_index == 0)
    {
        CommandObject::AddNamesMatchingPartialString (m_subcommand_dict, 
                                                      arg0,
                                                      matches);

        if (matches.GetSize() == 1
            && matches.GetStringAtIndex(0) != NULL
            && strcmp (arg0, matches.GetStringAtIndex(0)) == 0)
        {
            StringList temp_matches;
            CommandObject *cmd_obj = GetSubcommandObject (arg0,
                                                          &temp_matches);
            if (cmd_obj != NULL)
            {
                if (input.GetArgumentCount() == 1)
                {
                    word_complete = true;
                }
                else
                {
                    matches.DeleteStringAtIndex (0);
                    input.Shift();
                    cursor_char_position = 0;
                    input.AppendArgument ("");
                    return cmd_obj->HandleCompletion (input,
                                                      cursor_index,
                                                      cursor_char_position,
                                                      match_start_point,
                                                      max_return_elements,
                                                      word_complete,
                                                      matches);
                }
            }
        }
        return matches.GetSize();
    }
    else
    {
        CommandObject *sub_command_object = GetSubcommandObject (arg0,
                                                                 &matches);
        if (sub_command_object == NULL)
        {
            return matches.GetSize();
        }
        else
        {
            // Remove the one match that we got from calling GetSubcommandObject.
            matches.DeleteStringAtIndex(0);
            input.Shift();
            cursor_index--;
            return sub_command_object->HandleCompletion (input, 
                                                         cursor_index, 
                                                         cursor_char_position, 
                                                         match_start_point,
                                                         max_return_elements,
                                                         word_complete,
                                                         matches);
        }

    }
}

const char *
CommandObjectMultiword::GetRepeatCommand (Args &current_command_args, uint32_t index)
{
    index++;
    if (current_command_args.GetArgumentCount() <= index)
        return NULL;
    CommandObject *sub_command_object = GetSubcommandObject (current_command_args.GetArgumentAtIndex(index));
    if (sub_command_object == NULL)
        return NULL;
    return sub_command_object->GetRepeatCommand(current_command_args, index);
}


void
CommandObjectMultiword::AproposAllSubCommands (const char *prefix,
                                               const char *search_word,
                                               StringList &commands_found,
                                               StringList &commands_help)
{
    CommandObject::CommandMap::const_iterator pos;

    for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos)
    {
        const char * command_name = pos->first.c_str();
        CommandObject *sub_cmd_obj = pos->second.get();
        StreamString complete_command_name;
        
        complete_command_name.Printf ("%s %s", prefix, command_name);
        
        if (sub_cmd_obj->HelpTextContainsWord (search_word))
        {
            commands_found.AppendString (complete_command_name.GetData());
            commands_help.AppendString (sub_cmd_obj->GetHelp());
        }
        
        if (sub_cmd_obj->IsMultiwordObject())
            sub_cmd_obj->AproposAllSubCommands (complete_command_name.GetData(),
                                                search_word,
                                                commands_found,
                                                commands_help);
    }
}



CommandObjectProxy::CommandObjectProxy (CommandInterpreter &interpreter,
                                        const char *name,
                                        const char *help,
                                        const char *syntax,
                                        uint32_t flags) :
    CommandObject (interpreter, name, help, syntax, flags)
{
}

CommandObjectProxy::~CommandObjectProxy ()
{
}

const char *
CommandObjectProxy::GetHelpLong ()
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->GetHelpLong();
    return NULL;
}

bool
CommandObjectProxy::IsRemovable() const
{
    const CommandObject *proxy_command = const_cast<CommandObjectProxy *>(this)->GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->IsRemovable();
    return false;
}

bool
CommandObjectProxy::IsMultiwordObject ()
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->IsMultiwordObject();
    return false;
}

void
CommandObjectProxy::GenerateHelpText (Stream &result)
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->GenerateHelpText(result);
}

lldb::CommandObjectSP
CommandObjectProxy::GetSubcommandSP (const char *sub_cmd, StringList *matches)
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->GetSubcommandSP(sub_cmd, matches);
    return lldb::CommandObjectSP();
}

CommandObject *
CommandObjectProxy::GetSubcommandObject (const char *sub_cmd, StringList *matches)
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->GetSubcommandObject(sub_cmd, matches);
    return NULL;
}

void
CommandObjectProxy::AproposAllSubCommands (const char *prefix,
                                           const char *search_word,
                                           StringList &commands_found,
                                           StringList &commands_help)
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->AproposAllSubCommands (prefix,
                                                     search_word,
                                                     commands_found,
                                                     commands_help);
}

bool
CommandObjectProxy::LoadSubCommand (const char *cmd_name,
                                    const lldb::CommandObjectSP& command_sp)
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->LoadSubCommand (cmd_name, command_sp);
    return false;
}

bool
CommandObjectProxy::WantsRawCommandString()
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->WantsRawCommandString();
    return false;
}

bool
CommandObjectProxy::WantsCompletion()
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->WantsCompletion();
    return false;
}


Options *
CommandObjectProxy::GetOptions ()
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->GetOptions ();
    return NULL;
}


int
CommandObjectProxy::HandleCompletion (Args &input,
                                      int &cursor_index,
                                      int &cursor_char_position,
                                      int match_start_point,
                                      int max_return_elements,
                                      bool &word_complete,
                                      StringList &matches)
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->HandleCompletion (input,
                                                cursor_index,
                                                cursor_char_position,
                                                match_start_point,
                                                max_return_elements,
                                                word_complete,
                                                matches);
    matches.Clear();
    return 0;
}
int
CommandObjectProxy::HandleArgumentCompletion (Args &input,
                                              int &cursor_index,
                                              int &cursor_char_position,
                                              OptionElementVector &opt_element_vector,
                                              int match_start_point,
                                              int max_return_elements,
                                              bool &word_complete,
                                              StringList &matches)
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->HandleArgumentCompletion (input,
                                                        cursor_index,
                                                        cursor_char_position,
                                                        opt_element_vector,
                                                        match_start_point,
                                                        max_return_elements,
                                                        word_complete,
                                                        matches);
    matches.Clear();
    return 0;
}

const char *
CommandObjectProxy::GetRepeatCommand (Args &current_command_args,
                                      uint32_t index)
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->GetRepeatCommand (current_command_args, index);
    return NULL;
}

bool
CommandObjectProxy::Execute (const char *args_string,
                             CommandReturnObject &result)
{
    CommandObject *proxy_command = GetProxyCommandObject();
    if (proxy_command)
        return proxy_command->Execute (args_string, result);
    result.AppendError ("command is not implemented");
    result.SetStatus (eReturnStatusFailed);
    return false;
}


