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

#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Stream.h"

using namespace lldb;
using namespace lldb_private;

static bool VerifyPathExists(const char *path) {
  if (path && path[0])
    return FileSystem::Instance().Exists(path);
  else
    return false;
}

void OptionValuePathMappings::DumpValue(const ExecutionContext *exe_ctx,
                                        Stream &strm, uint32_t dump_mask) {
  if (dump_mask & eDumpOptionType)
    strm.Printf("(%s)", GetTypeAsCString());
  if (dump_mask & eDumpOptionValue) {
    if (dump_mask & (eDumpOptionType | eDumpOptionDefaultValue)) {
      strm.PutCString(" =");
      if (dump_mask & eDumpOptionDefaultValue && !m_path_mappings.IsEmpty()) {
        DefaultValueFormat label(strm);
        strm.PutCString("empty");
      }
      if (!m_path_mappings.IsEmpty())
        strm.PutCString("\n");
    }
    m_path_mappings.Dump(&strm);
  }
}

llvm::json::Value
OptionValuePathMappings::ToJSON(const ExecutionContext *exe_ctx) const {
  return m_path_mappings.ToJSON();
}

Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value,
                                                   VarSetOperationType op) {
  Status error;
  Args args(value.str());
  const size_t argc = args.GetArgumentCount();

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

  case eVarSetOperationReplace:
    // Must be at least one index + 1 pair of paths, and the pair count must be
    // even
    if (argc >= 3 && (((argc - 1) & 1) == 0)) {
      uint32_t idx;
      const uint32_t count = m_path_mappings.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 {
        bool changed = false;
        for (size_t i = 1; i < argc; idx++, i += 2) {
          const char *orginal_path = args.GetArgumentAtIndex(i);
          const char *replace_path = args.GetArgumentAtIndex(i + 1);
          if (VerifyPathExists(replace_path)) {
            if (!m_path_mappings.Replace(orginal_path, replace_path, idx,
                                         m_notify_changes))
              m_path_mappings.Append(orginal_path, replace_path,
                                     m_notify_changes);
            changed = true;
          } else {
            std::string previousError =
                error.Fail() ? std::string(error.AsCString()) + "\n" : "";
            error = Status::FromErrorStringWithFormat(
                "%sthe replacement path doesn't exist: \"%s\"",
                previousError.c_str(), replace_path);
          }
        }
        if (changed)
          NotifyValueChanged();
      }
    } else {
      error = Status::FromErrorString(
          "replace operation takes an array index followed by "
          "one or more path pairs");
    }
    break;

  case eVarSetOperationAssign:
    if (argc < 2 || (argc & 1)) {
      error = Status::FromErrorString(
          "assign operation takes one or more path pairs");
      break;
    }
    m_path_mappings.Clear(m_notify_changes);
    // Fall through to append case
    [[fallthrough]];
  case eVarSetOperationAppend:
    if (argc < 2 || (argc & 1)) {
      error = Status::FromErrorString(
          "append operation takes one or more path pairs");
      break;
    } else {
      bool changed = false;
      for (size_t i = 0; i < argc; i += 2) {
        const char *orginal_path = args.GetArgumentAtIndex(i);
        const char *replace_path = args.GetArgumentAtIndex(i + 1);
        if (VerifyPathExists(replace_path)) {
          m_path_mappings.Append(orginal_path, replace_path, m_notify_changes);
          m_value_was_set = true;
          changed = true;
        } else {
          std::string previousError =
              error.Fail() ? std::string(error.AsCString()) + "\n" : "";
          error = Status::FromErrorStringWithFormat(
              "%sthe replacement path doesn't exist: \"%s\"",
              previousError.c_str(), replace_path);
        }
      }
      if (changed)
        NotifyValueChanged();
    }
    break;

  case eVarSetOperationInsertBefore:
  case eVarSetOperationInsertAfter:
    // Must be at least one index + 1 pair of paths, and the pair count must be
    // even
    if (argc >= 3 && (((argc - 1) & 1) == 0)) {
      uint32_t idx;
      const uint32_t count = m_path_mappings.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 {
        bool changed = false;
        if (op == eVarSetOperationInsertAfter)
          ++idx;
        for (size_t i = 1; i < argc; i += 2) {
          const char *orginal_path = args.GetArgumentAtIndex(i);
          const char *replace_path = args.GetArgumentAtIndex(i + 1);
          if (VerifyPathExists(replace_path)) {
            m_path_mappings.Insert(orginal_path, replace_path, idx,
                                   m_notify_changes);
            changed = true;
            idx++;
          } else {
            std::string previousError =
                error.Fail() ? std::string(error.AsCString()) + "\n" : "";
            error = Status::FromErrorStringWithFormat(
                "%sthe replacement path doesn't exist: \"%s\"",
                previousError.c_str(), replace_path);
          }
        }
        if (changed)
          NotifyValueChanged();
      }
    } else {
      error = Status::FromErrorString(
          "insert operation takes an array index followed by "
          "one or more path pairs");
    }
    break;

  case eVarSetOperationRemove:
    if (argc > 0) {
      std::vector<int> remove_indexes;
      for (size_t i = 0; i < argc; ++i) {
        int idx;
        if (!llvm::to_integer(args.GetArgumentAtIndex(i), idx) || idx < 0 ||
            idx >= (int)m_path_mappings.GetSize()) {
          error = Status::FromErrorStringWithFormat(
              "invalid array index '%s', aborting remove operation",
              args.GetArgumentAtIndex(i));
          break;
        } else
          remove_indexes.push_back(idx);
      }

      // Sort and then erase in reverse so indexes are always valid
      llvm::sort(remove_indexes);
      for (auto index : llvm::reverse(remove_indexes))
        m_path_mappings.Remove(index, m_notify_changes);
      NotifyValueChanged();
    } else {
      error = Status::FromErrorString(
          "remove operation takes one or more array index");
    }
    break;

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