//===-- CommandObjectVersion.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "CommandObjectVersion.h"

#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Version/Version.h"
#include "llvm/ADT/StringExtras.h"

using namespace lldb;
using namespace lldb_private;

#define LLDB_OPTIONS_version
#include "CommandOptions.inc"

llvm::ArrayRef<OptionDefinition>
CommandObjectVersion::CommandOptions::GetDefinitions() {
  return llvm::ArrayRef(g_version_options);
}

CommandObjectVersion::CommandObjectVersion(CommandInterpreter &interpreter)
    : CommandObjectParsed(interpreter, "version",
                          "Show the LLDB debugger version.", "version") {}

CommandObjectVersion::~CommandObjectVersion() = default;

// Dump the array values on a single line.
static void dump(const StructuredData::Array &array, Stream &s) {
  std::vector<std::string> values;
  array.ForEach([&](StructuredData::Object *object) -> bool {
    values.emplace_back(object->GetStringValue().str());
    return true;
  });

  s << '[' << llvm::join(values, ", ") << ']';
}

static void dump(const StructuredData::Dictionary &config, Stream &s) {
  // Dump the keys in alphabetical order.
  llvm::SmallVector<llvm::StringRef> keys;
  keys.reserve(config.GetSize());
  config.ForEach(
      [&keys](llvm::StringRef key, StructuredData::Object *) -> bool {
        keys.push_back(key);
        return true;
      });
  llvm::sort(keys);

  for (auto key : keys) {
    StructuredData::ObjectSP object = config.GetValueForKey(key);
    assert(object);

    StructuredData::Dictionary *value_dict = object->GetAsDictionary();
    assert(value_dict);

    StructuredData::ObjectSP value_sp = value_dict->GetValueForKey("value");
    assert(value_sp);

    s << "  " << key << ": ";
    if (StructuredData::Boolean *boolean = value_sp->GetAsBoolean())
      s << (boolean->GetValue() ? "yes" : "no");
    else if (StructuredData::Array *array = value_sp->GetAsArray())
      dump(*array, s);
    s << '\n';
  }
}

void CommandObjectVersion::DoExecute(Args &args, CommandReturnObject &result) {
  result.AppendMessageWithFormatv("{0}", lldb_private::GetVersion());

  if (m_options.verbose)
    dump(*Debugger::GetBuildConfiguration(), result.GetOutputStream());

  result.SetStatus(eReturnStatusSuccessFinishResult);
}
