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

#include "lldb/Utility/Flags.h"

#include "lldb/Core/UserSettingsController.h"
#include "lldb/Interpreter/OptionValues.h"
#include "lldb/Interpreter/Property.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"

using namespace lldb;
using namespace lldb_private;

OptionValueProperties::OptionValueProperties(llvm::StringRef name)
    : m_name(name.str()) {}

void OptionValueProperties::Initialize(
    const PropertyCollectionDefinition &defs) {
  for (const auto &definition : defs.definitions) {
    Property property(definition);
    assert(property.IsValid());
    m_name_to_index.insert({property.GetName(), m_properties.size()});
    property.GetValue()->SetParent(shared_from_this());
    m_properties.push_back(property);
  }
  SetExpectedPath(defs.expected_path.str());
}

void OptionValueProperties::SetExpectedPath(std::string path) {
  assert(m_expected_path.empty() || m_expected_path == path);
  m_expected_path = path;
}

void OptionValueProperties::SetValueChangedCallback(
    size_t property_idx, std::function<void()> callback) {
  Property *property = ProtectedGetPropertyAtIndex(property_idx);
  if (property)
    property->SetValueChangedCallback(std::move(callback));
}

void OptionValueProperties::AppendProperty(llvm::StringRef name,
                                           llvm::StringRef desc, bool is_global,
                                           const OptionValueSP &value_sp) {
  Property property(name, desc, is_global, value_sp);
  m_name_to_index.insert({name, m_properties.size()});
  m_properties.push_back(property);
  value_sp->SetParent(shared_from_this());

#ifndef NDEBUG
  OptionValueProperties *properties = value_sp->GetAsProperties();
  if (properties) {
    assert(value_sp->GetName() == name);
    assert(properties->VerifyPath() &&
           "Mismatch between parents from TableGen and actual parents");
  }
#endif
}

lldb::OptionValueSP
OptionValueProperties::GetValueForKey(const ExecutionContext *exe_ctx,
                                      llvm::StringRef key) const {
  auto iter = m_name_to_index.find(key);
  if (iter == m_name_to_index.end())
    return OptionValueSP();
  const size_t idx = iter->second;
  if (idx >= m_properties.size())
    return OptionValueSP();
  return GetPropertyAtIndex(idx, exe_ctx)->GetValue();
}

lldb::OptionValueSP
OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx,
                                   llvm::StringRef name, Status &error) const {
  lldb::OptionValueSP value_sp;
  if (name.empty())
    return OptionValueSP();

  llvm::StringRef sub_name;
  llvm::StringRef key;
  size_t key_len = name.find_first_of(".[{");
  if (key_len != llvm::StringRef::npos) {
    key = name.take_front(key_len);
    sub_name = name.drop_front(key_len);
  } else
    key = name;

  value_sp = GetValueForKey(exe_ctx, key);
  if (sub_name.empty() || !value_sp)
    return value_sp;

  switch (sub_name[0]) {
  case '.': {
    lldb::OptionValueSP return_val_sp;
    return_val_sp =
        value_sp->GetSubValue(exe_ctx, sub_name.drop_front(), error);
    if (!return_val_sp) {
      if (Properties::IsSettingExperimental(sub_name.drop_front())) {
        const size_t experimental_len =
            Properties::GetExperimentalSettingsName().size();
        if (sub_name[experimental_len + 1] == '.')
          return_val_sp = value_sp->GetSubValue(
              exe_ctx, sub_name.drop_front(experimental_len + 2), error);
        // It isn't an error if an experimental setting is not present.
        if (!return_val_sp)
          error.Clear();
      }
    }
    return return_val_sp;
  }
  case '[':
    // Array or dictionary access for subvalues like: "[12]"       -- access
    // 12th array element "['hello']"  -- dictionary access of key named hello
    return value_sp->GetSubValue(exe_ctx, sub_name, error);

  default:
    value_sp.reset();
    break;
  }
  return value_sp;
}

Status OptionValueProperties::SetSubValue(const ExecutionContext *exe_ctx,
                                          VarSetOperationType op,
                                          llvm::StringRef name,
                                          llvm::StringRef value) {
  Status error;
  llvm::SmallVector<llvm::StringRef, 8> components;
  name.split(components, '.');
  bool name_contains_experimental = false;
  for (const auto &part : components)
    if (Properties::IsSettingExperimental(part))
      name_contains_experimental = true;

  lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, error));
  if (value_sp)
    error = value_sp->SetValueFromString(value, op);
  else {
    // Don't set an error if the path contained .experimental. - those are
    // allowed to be missing and should silently fail.
    if (!name_contains_experimental && error.AsCString() == nullptr) {
      error = Status::FromErrorStringWithFormat("invalid value path '%s'",
                                                name.str().c_str());
    }
  }
  return error;
}

size_t OptionValueProperties::GetPropertyIndex(llvm::StringRef name) const {
  auto iter = m_name_to_index.find(name);
  if (iter == m_name_to_index.end())
    return SIZE_MAX;
  return iter->second;
}

const Property *
OptionValueProperties::GetProperty(llvm::StringRef name,
                                   const ExecutionContext *exe_ctx) const {
  auto iter = m_name_to_index.find(name);
  if (iter == m_name_to_index.end())
    return nullptr;
  return GetPropertyAtIndex(iter->second, exe_ctx);
}

lldb::OptionValueSP OptionValueProperties::GetPropertyValueAtIndex(
    size_t idx, const ExecutionContext *exe_ctx) const {
  const Property *setting = GetPropertyAtIndex(idx, exe_ctx);
  if (setting)
    return setting->GetValue();
  return OptionValueSP();
}

OptionValuePathMappings *
OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings(
    size_t idx, const ExecutionContext *exe_ctx) const {
  OptionValueSP value_sp(GetPropertyValueAtIndex(idx, exe_ctx));
  if (value_sp)
    return value_sp->GetAsPathMappings();
  return nullptr;
}

OptionValueFileSpecList *
OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList(
    size_t idx, const ExecutionContext *exe_ctx) const {
  OptionValueSP value_sp(GetPropertyValueAtIndex(idx, exe_ctx));
  if (value_sp)
    return value_sp->GetAsFileSpecList();
  return nullptr;
}

bool OptionValueProperties::GetPropertyAtIndexAsArgs(
    size_t idx, Args &args, const ExecutionContext *exe_ctx) const {
  const Property *property = GetPropertyAtIndex(idx, exe_ctx);
  if (!property)
    return false;

  OptionValue *value = property->GetValue().get();
  if (!value)
    return false;

  const OptionValueArgs *arguments = value->GetAsArgs();
  if (arguments) {
    arguments->GetArgs(args);
    return true;
  }

  const OptionValueArray *array = value->GetAsArray();
  if (array) {
    array->GetArgs(args);
    return true;
  }

  const OptionValueDictionary *dict = value->GetAsDictionary();
  if (dict) {
    dict->GetArgs(args);
    return true;
  }

  return false;
}

bool OptionValueProperties::SetPropertyAtIndexFromArgs(
    size_t idx, const Args &args, const ExecutionContext *exe_ctx) {
  const Property *property = GetPropertyAtIndex(idx, exe_ctx);
  if (!property)
    return false;

  OptionValue *value = property->GetValue().get();
  if (!value)
    return false;

  OptionValueArgs *arguments = value->GetAsArgs();
  if (arguments)
    return arguments->SetArgs(args, eVarSetOperationAssign).Success();

  OptionValueArray *array = value->GetAsArray();
  if (array)
    return array->SetArgs(args, eVarSetOperationAssign).Success();

  OptionValueDictionary *dict = value->GetAsDictionary();
  if (dict)
    return dict->SetArgs(args, eVarSetOperationAssign).Success();

  return false;
}

OptionValueDictionary *
OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary(
    size_t idx, const ExecutionContext *exe_ctx) const {
  const Property *property = GetPropertyAtIndex(idx, exe_ctx);
  if (property)
    return property->GetValue()->GetAsDictionary();
  return nullptr;
}

OptionValueFileSpec *
OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec(
    size_t idx, const ExecutionContext *exe_ctx) const {
  const Property *property = GetPropertyAtIndex(idx, exe_ctx);
  if (property) {
    OptionValue *value = property->GetValue().get();
    if (value)
      return value->GetAsFileSpec();
  }
  return nullptr;
}

OptionValueSInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64(
    size_t idx, const ExecutionContext *exe_ctx) const {
  const Property *property = GetPropertyAtIndex(idx, exe_ctx);
  if (property) {
    OptionValue *value = property->GetValue().get();
    if (value)
      return value->GetAsSInt64();
  }
  return nullptr;
}

OptionValueUInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueUInt64(
    size_t idx, const ExecutionContext *exe_ctx) const {
  const Property *property = GetPropertyAtIndex(idx, exe_ctx);
  if (property) {
    OptionValue *value = property->GetValue().get();
    if (value)
      return value->GetAsUInt64();
  }
  return nullptr;
}

OptionValueString *OptionValueProperties::GetPropertyAtIndexAsOptionValueString(
    size_t idx, const ExecutionContext *exe_ctx) const {
  OptionValueSP value_sp(GetPropertyValueAtIndex(idx, exe_ctx));
  if (value_sp)
    return value_sp->GetAsString();
  return nullptr;
}

void OptionValueProperties::Clear() {
  const size_t num_properties = m_properties.size();
  for (size_t i = 0; i < num_properties; ++i)
    m_properties[i].GetValue()->Clear();
}

Status OptionValueProperties::SetValueFromString(llvm::StringRef value,
                                                 VarSetOperationType op) {
  Status error;

  //    Args args(value_cstr);
  //    const size_t argc = args.GetArgumentCount();
  switch (op) {
  case eVarSetOperationClear:
    Clear();
    break;

  case eVarSetOperationReplace:
  case eVarSetOperationAssign:
  case eVarSetOperationRemove:
  case eVarSetOperationInsertBefore:
  case eVarSetOperationInsertAfter:
  case eVarSetOperationAppend:
  case eVarSetOperationInvalid:
    error = OptionValue::SetValueFromString(value, op);
    break;
  }

  return error;
}

void OptionValueProperties::DumpValue(const ExecutionContext *exe_ctx,
                                      Stream &strm, uint32_t dump_mask) {
  const size_t num_properties = m_properties.size();
  for (size_t i = 0; i < num_properties; ++i) {
    const Property *property = GetPropertyAtIndex(i, exe_ctx);
    if (property) {
      OptionValue *option_value = property->GetValue().get();
      assert(option_value);
      const bool transparent_value = option_value->ValueIsTransparent();
      property->Dump(exe_ctx, strm, dump_mask);
      if (!transparent_value)
        strm.EOL();
    }
  }
}

llvm::json::Value
OptionValueProperties::ToJSON(const ExecutionContext *exe_ctx) const {
  llvm::json::Object json_properties;
  const size_t num_properties = m_properties.size();
  for (size_t i = 0; i < num_properties; ++i) {
    const Property *property = GetPropertyAtIndex(i, exe_ctx);
    if (property) {
      OptionValue *option_value = property->GetValue().get();
      assert(option_value);
      json_properties.try_emplace(property->GetName(),
                                  option_value->ToJSON(exe_ctx));
    }
  }
  return json_properties;
}

Status OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx,
                                                Stream &strm,
                                                llvm::StringRef property_path,
                                                uint32_t dump_mask,
                                                bool is_json) {
  Status error;
  lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, property_path, error));
  if (value_sp) {
    if (!value_sp->ValueIsTransparent()) {
      if (dump_mask & eDumpOptionName)
        strm.PutCString(property_path);
      if (dump_mask & ~eDumpOptionName)
        strm.PutChar(' ');
    }
    if (is_json)
      strm << llvm::formatv("{0:2}", value_sp->ToJSON(exe_ctx));
    else
      value_sp->DumpValue(exe_ctx, strm, dump_mask);
  }
  return error;
}

OptionValuePropertiesSP
OptionValueProperties::CreateLocalCopy(const Properties &global_properties) {
  auto global_props_sp = global_properties.GetValueProperties();
  lldbassert(global_props_sp);

  auto copy_sp = global_props_sp->DeepCopy(global_props_sp->GetParent());
  return std::static_pointer_cast<OptionValueProperties>(copy_sp);
}

OptionValueSP
OptionValueProperties::DeepCopy(const OptionValueSP &new_parent) const {
  auto copy_sp = OptionValue::DeepCopy(new_parent);
  // copy_sp->GetAsProperties cannot be used here as it doesn't work for derived
  // types that override GetType returning a different value.
  auto *props_value_ptr = static_cast<OptionValueProperties *>(copy_sp.get());
  lldbassert(props_value_ptr);

  for (auto &property : props_value_ptr->m_properties) {
    // Duplicate any values that are not global when constructing properties
    // from a global copy.
    if (!property.IsGlobal()) {
      auto value_sp = property.GetValue()->DeepCopy(copy_sp);
      property.SetOptionValue(value_sp);
    }
  }
  return copy_sp;
}

const Property *
OptionValueProperties::GetPropertyAtPath(const ExecutionContext *exe_ctx,
                                         llvm::StringRef name) const {
  if (name.empty())
    return nullptr;

  const Property *property = nullptr;
  llvm::StringRef sub_name;
  llvm::StringRef key;
  size_t key_len = name.find_first_of(".[{");

  if (key_len != llvm::StringRef::npos) {
    key = name.take_front(key_len);
    sub_name = name.drop_front(key_len);
  } else
    key = name;

  property = GetProperty(key, exe_ctx);
  if (sub_name.empty() || !property)
    return property;

  if (sub_name[0] == '.') {
    OptionValueProperties *sub_properties =
        property->GetValue()->GetAsProperties();
    if (sub_properties)
      return sub_properties->GetPropertyAtPath(exe_ctx, sub_name.drop_front());
  }
  return nullptr;
}

void OptionValueProperties::DumpAllDescriptions(CommandInterpreter &interpreter,
                                                Stream &strm) const {
  size_t max_name_len = 0;
  const size_t num_properties = m_properties.size();
  for (size_t i = 0; i < num_properties; ++i) {
    const Property *property = ProtectedGetPropertyAtIndex(i);
    if (property)
      max_name_len = std::max<size_t>(property->GetName().size(), max_name_len);
  }
  for (size_t i = 0; i < num_properties; ++i) {
    const Property *property = ProtectedGetPropertyAtIndex(i);
    if (property)
      property->DumpDescription(interpreter, strm, max_name_len, false);
  }
}

void OptionValueProperties::Apropos(
    llvm::StringRef keyword,
    std::vector<const Property *> &matching_properties) const {
  const size_t num_properties = m_properties.size();
  StreamString strm;
  for (size_t i = 0; i < num_properties; ++i) {
    const Property *property = ProtectedGetPropertyAtIndex(i);
    if (property) {
      const OptionValueProperties *properties =
          property->GetValue()->GetAsProperties();
      if (properties) {
        properties->Apropos(keyword, matching_properties);
      } else {
        bool match = false;
        llvm::StringRef name = property->GetName();
        if (name.contains_insensitive(keyword))
          match = true;
        else {
          llvm::StringRef desc = property->GetDescription();
          if (desc.contains_insensitive(keyword))
            match = true;
        }
        if (match) {
          matching_properties.push_back(property);
        }
      }
    }
  }
}

lldb::OptionValuePropertiesSP
OptionValueProperties::GetSubProperty(const ExecutionContext *exe_ctx,
                                      llvm::StringRef name) {
  lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name));
  if (option_value_sp) {
    OptionValueProperties *ov_properties = option_value_sp->GetAsProperties();
    if (ov_properties)
      return ov_properties->shared_from_this();
  }
  return lldb::OptionValuePropertiesSP();
}

bool OptionValueProperties::VerifyPath() {
  OptionValueSP parent = GetParent();
  if (!parent) {
    // Only the top level value should have an empty path.
    return m_expected_path.empty();
  }
  OptionValueProperties *parent_properties = parent->GetAsProperties();
  if (!parent_properties)
    return false;

  auto [prefix, expected_name] = llvm::StringRef(m_expected_path).rsplit('.');

  if (expected_name.empty()) {
    // There is no dot, so the parent should be the top-level (core properties).
    return parent_properties->m_expected_path.empty() && GetName() == prefix;
  }

  return parent_properties->m_expected_path == prefix &&
         GetName() == expected_name;
}
