//===-- VariableList.cpp ----------------------------------------*- C++ -*-===//
//
// 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/Symbol/VariableList.h"

#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Utility/RegularExpression.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// VariableList constructor
//----------------------------------------------------------------------
VariableList::VariableList() : m_variables() {}

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

void VariableList::AddVariable(const VariableSP &var_sp) {
  m_variables.push_back(var_sp);
}

bool VariableList::AddVariableIfUnique(const lldb::VariableSP &var_sp) {
  if (FindVariableIndex(var_sp) == UINT32_MAX) {
    m_variables.push_back(var_sp);
    return true;
  }
  return false;
}

void VariableList::AddVariables(VariableList *variable_list) {
  if (variable_list) {
    std::copy(variable_list->m_variables.begin(), // source begin
              variable_list->m_variables.end(),   // source end
              back_inserter(m_variables));        // destination
  }
}

void VariableList::Clear() { m_variables.clear(); }

VariableSP VariableList::GetVariableAtIndex(size_t idx) const {
  VariableSP var_sp;
  if (idx < m_variables.size())
    var_sp = m_variables[idx];
  return var_sp;
}

VariableSP VariableList::RemoveVariableAtIndex(size_t idx) {
  VariableSP var_sp;
  if (idx < m_variables.size()) {
    var_sp = m_variables[idx];
    m_variables.erase(m_variables.begin() + idx);
  }
  return var_sp;
}

uint32_t VariableList::FindVariableIndex(const VariableSP &var_sp) {
  iterator pos, end = m_variables.end();
  for (pos = m_variables.begin(); pos != end; ++pos) {
    if (pos->get() == var_sp.get())
      return std::distance(m_variables.begin(), pos);
  }
  return UINT32_MAX;
}

VariableSP VariableList::FindVariable(const ConstString &name,
                                      bool include_static_members) {
  VariableSP var_sp;
  iterator pos, end = m_variables.end();
  for (pos = m_variables.begin(); pos != end; ++pos) {
    if ((*pos)->NameMatches(name)) {
      if (include_static_members || !(*pos)->IsStaticMember()) {
        var_sp = (*pos);
        break;
      }
    }
  }
  return var_sp;
}

VariableSP VariableList::FindVariable(const ConstString &name,
                                      lldb::ValueType value_type,
                                      bool include_static_members) {
  VariableSP var_sp;
  iterator pos, end = m_variables.end();
  for (pos = m_variables.begin(); pos != end; ++pos) {
    if ((*pos)->NameMatches(name) && (*pos)->GetScope() == value_type) {
      if (include_static_members || !(*pos)->IsStaticMember()) {
        var_sp = (*pos);
        break;
      }
    }
  }
  return var_sp;
}

size_t VariableList::AppendVariablesIfUnique(VariableList &var_list) {
  const size_t initial_size = var_list.GetSize();
  iterator pos, end = m_variables.end();
  for (pos = m_variables.begin(); pos != end; ++pos)
    var_list.AddVariableIfUnique(*pos);
  return var_list.GetSize() - initial_size;
}

size_t VariableList::AppendVariablesIfUnique(const RegularExpression &regex,
                                             VariableList &var_list,
                                             size_t &total_matches) {
  const size_t initial_size = var_list.GetSize();
  iterator pos, end = m_variables.end();
  for (pos = m_variables.begin(); pos != end; ++pos) {
    if ((*pos)->NameMatches(regex)) {
      // Note the total matches found
      total_matches++;
      // Only add this variable if it isn't already in the "var_list"
      var_list.AddVariableIfUnique(*pos);
    }
  }
  // Return the number of new unique variables added to "var_list"
  return var_list.GetSize() - initial_size;
}

size_t VariableList::AppendVariablesWithScope(lldb::ValueType type,
                                              VariableList &var_list,
                                              bool if_unique) {
  const size_t initial_size = var_list.GetSize();
  iterator pos, end = m_variables.end();
  for (pos = m_variables.begin(); pos != end; ++pos) {
    if ((*pos)->GetScope() == type) {
      if (if_unique)
        var_list.AddVariableIfUnique(*pos);
      else
        var_list.AddVariable(*pos);
    }
  }
  // Return the number of new unique variables added to "var_list"
  return var_list.GetSize() - initial_size;
}

uint32_t VariableList::FindIndexForVariable(Variable *variable) {
  VariableSP var_sp;
  iterator pos;
  const iterator begin = m_variables.begin();
  const iterator end = m_variables.end();
  for (pos = m_variables.begin(); pos != end; ++pos) {
    if ((*pos).get() == variable)
      return std::distance(begin, pos);
  }
  return UINT32_MAX;
}

size_t VariableList::MemorySize() const {
  size_t mem_size = sizeof(VariableList);
  const_iterator pos, end = m_variables.end();
  for (pos = m_variables.begin(); pos != end; ++pos)
    mem_size += (*pos)->MemorySize();
  return mem_size;
}

size_t VariableList::GetSize() const { return m_variables.size(); }

void VariableList::Dump(Stream *s, bool show_context) const {
  //  s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
  //  s.Indent();
  //  s << "VariableList\n";

  const_iterator pos, end = m_variables.end();
  for (pos = m_variables.begin(); pos != end; ++pos) {
    (*pos)->Dump(s, show_context);
  }
}
