//===-- CommandObjectSyntax.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 "CommandObjectSyntax.h"
#include "CommandObjectHelp.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"

using namespace lldb;
using namespace lldb_private;

//-------------------------------------------------------------------------
// CommandObjectSyntax
//-------------------------------------------------------------------------

CommandObjectSyntax::CommandObjectSyntax(CommandInterpreter &interpreter)
    : CommandObjectParsed(
          interpreter, "syntax",
          "Shows the correct syntax for a given debugger command.",
          "syntax <command>") {
  CommandArgumentEntry arg;
  CommandArgumentData command_arg;

  // Define the first (and only) variant of this arg.
  command_arg.arg_type = eArgTypeCommandName;
  command_arg.arg_repetition = eArgRepeatPlain;

  // There is only one variant this argument could be; put it into the argument
  // entry.
  arg.push_back(command_arg);

  // Push the data for the first argument into the m_arguments vector.
  m_arguments.push_back(arg);
}

CommandObjectSyntax::~CommandObjectSyntax() = default;

bool CommandObjectSyntax::DoExecute(Args &command,
                                    CommandReturnObject &result) {
  CommandObject::CommandMap::iterator pos;
  CommandObject *cmd_obj;
  const size_t argc = command.GetArgumentCount();

  if (argc > 0) {
    cmd_obj = m_interpreter.GetCommandObject(command.GetArgumentAtIndex(0));
    bool all_okay = true;
    for (size_t i = 1; i < argc; ++i) {
      std::string sub_command = command.GetArgumentAtIndex(i);
      if (!cmd_obj->IsMultiwordObject()) {
        all_okay = false;
        break;
      } else {
        cmd_obj = cmd_obj->GetSubcommandObject(sub_command.c_str());
        if (!cmd_obj) {
          all_okay = false;
          break;
        }
      }
    }

    if (all_okay && (cmd_obj != nullptr)) {
      Stream &output_strm = result.GetOutputStream();
      if (cmd_obj->GetOptions() != nullptr) {
        output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax());
        output_strm.Printf(
            "(Try 'help %s' for more information on command options syntax.)\n",
            cmd_obj->GetCommandName());
        result.SetStatus(eReturnStatusSuccessFinishNoResult);
      } else {
        output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax());
        result.SetStatus(eReturnStatusSuccessFinishNoResult);
      }
    } else {
      std::string cmd_string;
      command.GetCommandString(cmd_string);

      StreamString error_msg_stream;
      const bool generate_apropos = true;
      const bool generate_type_lookup = false;
      CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(
          &error_msg_stream, cmd_string.c_str(), nullptr, nullptr,
          generate_apropos, generate_type_lookup);
      result.AppendErrorWithFormat("%s", error_msg_stream.GetData());
      result.SetStatus(eReturnStatusFailed);
    }
  } else {
    result.AppendError("Must call 'syntax' with a valid command.");
    result.SetStatus(eReturnStatusFailed);
  }

  return result.Succeeded();
}
