//===-- OptionValueFileSpecList.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/OptionValueFileSpecList.h"

#include "lldb/Utility/Args.h"
#include "lldb/Utility/Stream.h"

using namespace lldb;
using namespace lldb_private;

void OptionValueFileSpecList::DumpValue(const ExecutionContext *exe_ctx,
                                        Stream &strm, uint32_t dump_mask) {
  std::lock_guard<std::recursive_mutex> lock(m_mutex);
  if (dump_mask & eDumpOptionType)
    strm.Printf("(%s)", GetTypeAsCString());
  if (dump_mask & eDumpOptionValue) {
    const bool one_line = dump_mask & eDumpOptionCommand;
    const uint32_t size = m_current_value.GetSize();
    if (dump_mask & eDumpOptionType)
      strm.Printf(" =%s",
                  (m_current_value.GetSize() > 0 && !one_line) ? "\n" : "");
    if (!one_line)
      strm.IndentMore();
    for (uint32_t i = 0; i < size; ++i) {
      if (!one_line) {
        strm.Indent();
        strm.Printf("[%u]: ", i);
      }
      m_current_value.GetFileSpecAtIndex(i).Dump(strm.AsRawOstream());
      if (one_line)
        strm << ' ';
    }
    if (!one_line)
      strm.IndentLess();
  }
}

Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value,
                                                   VarSetOperationType op) {
  std::lock_guard<std::recursive_mutex> lock(m_mutex);
  Status error;
  Args args(value.str());
  const size_t argc = args.GetArgumentCount();

  switch (op) {
  case eVarSetOperationClear:
    Clear();
    NotifyValueChanged();
    break;

  case eVarSetOperationReplace:
    if (argc > 1) {
      uint32_t idx;
      const uint32_t count = m_current_value.GetSize();
      if (!llvm::to_integer(args.GetArgumentAtIndex(0), idx) || idx > count) {
        error = Status::FromErrorStringWithFormat(
            "invalid file list index %s, index must be 0 through %u",
            args.GetArgumentAtIndex(0), count);
      } else {
        for (size_t i = 1; i < argc; ++i, ++idx) {
          FileSpec file(args.GetArgumentAtIndex(i));
          if (idx < count)
            m_current_value.Replace(idx, file);
          else
            m_current_value.Append(file);
        }
        NotifyValueChanged();
      }
    } else {
      error = Status::FromErrorString(
          "replace operation takes an array index followed by "
          "one or more values");
    }
    break;

  case eVarSetOperationAssign:
    m_current_value.Clear();
    // Fall through to append case
    [[fallthrough]];
  case eVarSetOperationAppend:
    if (argc > 0) {
      m_value_was_set = true;
      for (size_t i = 0; i < argc; ++i) {
        FileSpec file(args.GetArgumentAtIndex(i));
        m_current_value.Append(file);
      }
      NotifyValueChanged();
    } else {
      error = Status::FromErrorString(
          "assign operation takes at least one file path argument");
    }
    break;

  case eVarSetOperationInsertBefore:
  case eVarSetOperationInsertAfter:
    if (argc > 1) {
      uint32_t idx;
      const uint32_t count = m_current_value.GetSize();
      if (!llvm::to_integer(args.GetArgumentAtIndex(0), idx) || idx > count) {
        error = Status::FromErrorStringWithFormat(
            "invalid insert file list index %s, index must be 0 through %u",
            args.GetArgumentAtIndex(0), count);
      } else {
        if (op == eVarSetOperationInsertAfter)
          ++idx;
        for (size_t i = 1; i < argc; ++i, ++idx) {
          FileSpec file(args.GetArgumentAtIndex(i));
          m_current_value.Insert(idx, file);
        }
        NotifyValueChanged();
      }
    } else {
      error = Status::FromErrorString(
          "insert operation takes an array index followed by "
          "one or more values");
    }
    break;

  case eVarSetOperationRemove:
    if (argc > 0) {
      std::vector<int> remove_indexes;
      bool all_indexes_valid = true;
      size_t i;
      for (i = 0; all_indexes_valid && i < argc; ++i) {
        int idx;
        if (!llvm::to_integer(args.GetArgumentAtIndex(i), idx))
          all_indexes_valid = false;
        else
          remove_indexes.push_back(idx);
      }

      if (all_indexes_valid) {
        size_t num_remove_indexes = remove_indexes.size();
        if (num_remove_indexes) {
          // Sort and then erase in reverse so indexes are always valid
          llvm::sort(remove_indexes);
          for (size_t j = num_remove_indexes - 1; j < num_remove_indexes; ++j) {
            m_current_value.Remove(j);
          }
        }
        NotifyValueChanged();
      } else {
        error = Status::FromErrorStringWithFormat(
            "invalid array index '%s', aborting remove operation",
            args.GetArgumentAtIndex(i));
      }
    } else {
      error = Status::FromErrorString(
          "remove operation takes one or more array index");
    }
    break;

  case eVarSetOperationInvalid:
    error = OptionValue::SetValueFromString(value, op);
    break;
  }
  return error;
}

OptionValueSP OptionValueFileSpecList::Clone() const {
  std::lock_guard<std::recursive_mutex> lock(m_mutex);
  return Cloneable::Clone();
}
