// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "common/text/config_utils.h"

#include <cstdint>
#include <initializer_list>
#include <limits>
#include <string>
#include <vector>

#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "common/util/logging.h"

namespace verible {
using absl::string_view;
using config::NVConfigSpec;

// TODO(hzeller): consider using flex for a more readable tokenization that
// can also much easier deal with whitespaces, strings etc.
absl::Status ParseNameValues(string_view config_string,
                             const std::initializer_list<NVConfigSpec>& spec) {
  if (config_string.empty()) return absl::OkStatus();

  for (const string_view single_config : absl::StrSplit(config_string, ';')) {
    const std::pair<string_view, string_view> nv_pair =
        absl::StrSplit(single_config, ':');
    const auto value_config = std::find_if(  // linear search
        spec.begin(), spec.end(),
        [&nv_pair](const NVConfigSpec& s) { return nv_pair.first == s.name; });
    if (value_config == spec.end()) {
      std::string available;
      for (const auto& s : spec) {
        if (!available.empty()) available.append(", ");
        available.append("'").append(s.name).append("'");
      }
      const bool plural = spec.size() > 1;
      return absl::InvalidArgumentError(absl::StrCat(
          nv_pair.first, ": unknown parameter; supported ",
          (plural ? "parameters are " : "parameter is "), available));
    }
    if (!value_config->set_value) return absl::OkStatus();  // consume, not use.
    absl::Status result = value_config->set_value(nv_pair.second);
    if (!result.ok()) {
      // We always prepend the parameter name first in the message for
      // diagnostic usefulness of the error message.
      // Also, this way, the functor can just worry about parsing and does
      // not need to know the name of the value.
      return absl::InvalidArgumentError(
          absl::StrCat(nv_pair.first, ": ", result.message()));
    }
  }
  return absl::OkStatus();
}

namespace config {
ConfigValueSetter SetInt(int* value, int minimum, int maximum) {
  CHECK(value) << "Must provide pointer to integer to store.";
  return [value, minimum, maximum](string_view v) {
    int parsed_value;
    if (!absl::SimpleAtoi(v, &parsed_value)) {
      return absl::InvalidArgumentError(
          absl::StrCat("'", v, "': Cannot parse integer"));
    }
    if (parsed_value < minimum || parsed_value > maximum) {
      return absl::InvalidArgumentError(absl::StrCat(
          parsed_value, " out of range [", minimum, "...", maximum, "]"));
    }
    *value = parsed_value;
    return absl::OkStatus();
  };
}

ConfigValueSetter SetInt(int* value) {
  return SetInt(value, std::numeric_limits<int>::min(),
                std::numeric_limits<int>::max());
}

ConfigValueSetter SetBool(bool* value) {
  CHECK(value) << "Must provide pointer to boolean to store.";
  return [value](string_view v) {
    // clang-format off
    if (v.empty() || v == "1"
        || absl::EqualsIgnoreCase(v, "true")
        || absl::EqualsIgnoreCase(v, "on")) {
      *value = true;
      return absl::OkStatus();
    }
    if (v == "0"
        || absl::EqualsIgnoreCase(v, "false")
        || absl::EqualsIgnoreCase(v, "off")) {
      *value = false;
      return absl::OkStatus();
    }
    // clange-format on

    // We accept 1 and 0 silently to encourage somewhat
    // consistent use of values.
    return absl::InvalidArgumentError("Boolean value should be one of "
                                      "'true', 'on' or 'false', 'off'");
  };
}

// TODO(hzeller): For strings, consider to allow quoted strings that then also
// allow C-Escapes. But that would require that ParseNameValues() can properly
// deal with whitespace, which it might after converted to flex.

ConfigValueSetter SetString(std::string* value) {
  return [value](string_view v) {
           value->assign(v.data(), v.length());
           return absl::OkStatus();
         };
}

ConfigValueSetter SetStringOneOf(std::string* value,
                                 const std::vector<string_view>& allowed) {
  CHECK(value) << "Must provide pointer to string to store.";
  return [value, allowed](string_view v) {
           auto item = find(allowed.begin(), allowed.end(), v);
           if (item == allowed.end()) {
             // If the list only contains one element, provide a more suited
             // error message.
             if (allowed.size() == 1) {
               return absl::InvalidArgumentError(
                   absl::StrCat("Value can only be '", allowed[0], "'; got '",
                                v, "'"));
             } else {
               return absl::InvalidArgumentError(
                   absl::StrCat("Value can only be one of ['",
                                absl::StrJoin(allowed, "', '"),
                                "']; got '", v, "'"));
             }
           }
           value->assign(v.data(), v.length());
           return absl::OkStatus();
         };
}

ConfigValueSetter SetNamedBits(
    uint32_t* value,
    const std::vector<absl::string_view>& choices) {
  CHECK(value) << "Must provide pointer to uint32_t to store.";
  CHECK_LE(choices.size(), 32) << "Too many choices for 32-bit bitmap";
  return [value, choices](string_view v) {
           uint32_t result = 0;
           for (auto bitname : absl::StrSplit(v, '|', absl::SkipWhitespace())) {
             bitname = absl::StripAsciiWhitespace(bitname);
             const auto item_pos = find_if(
                 choices.begin(), choices.end(),
                 [bitname](string_view c) {
                   return absl::EqualsIgnoreCase(bitname, c);
                 });
             if (item_pos == choices.end()) {
               return absl::InvalidArgumentError(
                   absl::StrCat("'", bitname,
                                "' is not in the available choices {",
                                absl::StrJoin(choices, ", "), "}"));
             }
             result |= (1 << (std::distance(choices.begin(), item_pos)));
           }
           // Parsed all bits successfully.
           *value = result;
           return absl::OkStatus();
         };
}

}  // namespace config
}  // namespace verible
