/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2019,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "command-definition.hpp"

#include <ndn-cxx/util/logger.hpp>

namespace nfd {
namespace tools {
namespace nfdc {

NDN_LOG_INIT(nfdc.CommandDefinition);

std::ostream&
operator<<(std::ostream& os, ArgValueType vt)
{
  switch (vt) {
    case ArgValueType::NONE:
      return os << "none";
    case ArgValueType::ANY:
      return os << "any";
    case ArgValueType::BOOLEAN:
      return os << "boolean";
    case ArgValueType::UNSIGNED:
      return os << "non-negative integer";
    case ArgValueType::STRING:
      return os << "string";
    case ArgValueType::REPORT_FORMAT:
      return os << "ReportFormat";
    case ArgValueType::NAME:
      return os << "Name";
    case ArgValueType::FACE_URI:
      return os << "FaceUri";
    case ArgValueType::FACE_ID_OR_URI:
      return os << "FaceId or FaceUri";
    case ArgValueType::FACE_PERSISTENCY:
      return os << "FacePersistency";
    case ArgValueType::ROUTE_ORIGIN:
      return os << "RouteOrigin";
  }
  return os << static_cast<int>(vt);
}

static std::string
getMetavarFromType(ArgValueType vt)
{
  switch (vt) {
    case ArgValueType::NONE:
      return "";
    case ArgValueType::ANY:
      return "args";
    case ArgValueType::BOOLEAN:
      return "bool";
    case ArgValueType::UNSIGNED:
      return "uint";
    case ArgValueType::STRING:
      return "str";
    case ArgValueType::REPORT_FORMAT:
      return "fmt";
    case ArgValueType::NAME:
      return "name";
    case ArgValueType::FACE_URI:
      return "uri";
    case ArgValueType::FACE_ID_OR_URI:
      return "face";
    case ArgValueType::FACE_PERSISTENCY:
      return "persistency";
    case ArgValueType::ROUTE_ORIGIN:
      return "origin";
  }
  NDN_CXX_UNREACHABLE;
}

CommandDefinition::CommandDefinition(const std::string& noun, const std::string& verb)
  : m_noun(noun)
  , m_verb(verb)
{
}

CommandDefinition::~CommandDefinition() = default;

CommandDefinition&
CommandDefinition::addArg(const std::string& name, ArgValueType valueType,
                        Required isRequired, Positional allowPositional,
                        const std::string& metavar)
{
  bool isNew = m_args.emplace(name,
    Arg{name, valueType, static_cast<bool>(isRequired),
        metavar.empty() ? getMetavarFromType(valueType) : metavar}).second;
  BOOST_VERIFY(isNew);

  if (static_cast<bool>(isRequired)) {
    m_requiredArgs.insert(name);
  }

  if (static_cast<bool>(allowPositional)) {
    BOOST_ASSERT(valueType != ArgValueType::NONE);
    m_positionalArgs.push_back(name);
  }
  else {
    BOOST_ASSERT(valueType != ArgValueType::ANY);
  }

  return *this;
}

CommandArguments
CommandDefinition::parse(const std::vector<std::string>& tokens, size_t start) const
{
  CommandArguments ca;

  size_t positionalArgIndex = 0;
  for (size_t i = start; i < tokens.size(); ++i) {
    const std::string& token = tokens[i];

    // try to parse as named argument
    auto namedArg = m_args.find(token);
    if (namedArg != m_args.end() && namedArg->second.valueType != ArgValueType::ANY) {
      NDN_LOG_TRACE(token << " is a named argument");
      const Arg& arg = namedArg->second;
      if (arg.valueType == ArgValueType::NONE) {
        ca[arg.name] = true;
        NDN_LOG_TRACE(token << " is a no-param argument");
      }
      else if (i + 1 >= tokens.size()) {
        NDN_THROW(Error(arg.name + ": " + arg.metavar + " is missing"));
      }
      else {
        const std::string& valueToken = tokens[++i];
        NDN_LOG_TRACE(arg.name << " has value " << valueToken);
        try {
          ca[arg.name] = this->parseValue(arg.valueType, valueToken);
        }
        catch (const std::exception& e) {
          NDN_LOG_TRACE(valueToken << " cannot be parsed as " << arg.valueType);
          NDN_THROW_NESTED(Error(arg.name + ": cannot parse '" + valueToken + "' as " +
                                 arg.metavar + " (" + e.what() + ")"));
        }
        NDN_LOG_TRACE(valueToken << " is parsed as " << arg.valueType);
      }

      // disallow positional arguments after named argument
      positionalArgIndex = m_positionalArgs.size();
      continue;
    }

    // try to parse as positional argument
    for (; positionalArgIndex < m_positionalArgs.size(); ++positionalArgIndex) {
      const Arg& arg = m_args.at(m_positionalArgs[positionalArgIndex]);

      if (arg.valueType == ArgValueType::ANY) {
        std::vector<std::string> values;
        std::copy(tokens.begin() + i, tokens.end(), std::back_inserter(values));
        ca[arg.name] = values;
        NDN_LOG_TRACE((tokens.size() - i) << " tokens are consumed for " << arg.name);
        i = tokens.size();
        break;
      }

      try {
        ca[arg.name] = this->parseValue(arg.valueType, token);
        NDN_LOG_TRACE(token << " is parsed as value for " << arg.name);
        break;
      }
      catch (const std::exception& e) {
        if (arg.isRequired) { // the current token must be parsed as the value for arg
          NDN_LOG_TRACE(token << " cannot be parsed as value for " << arg.name);
          NDN_THROW_NESTED(Error("cannot parse '" + token + "' as an argument name or as " +
                                 arg.metavar + " for " + arg.name + " (" + e.what() + ")"));
        }
        else {
          // the current token may be a value for next positional argument
          NDN_LOG_TRACE(token << " cannot be parsed as value for " << arg.name);
        }
      }
    }

    if (positionalArgIndex >= m_positionalArgs.size()) {
      // for loop has reached the end without finding a match,
      // which means token is not accepted as a value for positional argument
      NDN_THROW(Error("cannot parse '" + token + "' as an argument name"));
    }

    // token is accepted; don't parse as the same positional argument again
    ++positionalArgIndex;
  }

  for (const std::string& argName : m_requiredArgs) {
    if (ca.count(argName) == 0) {
      NDN_THROW(Error(argName + ": required argument is missing"));
    }
  }

  return ca;
}

static bool
parseBoolean(const std::string& s)
{
  if (s == "on" || s == "true" || s == "enabled" || s == "yes" || s == "1") {
    return true;
  }
  if (s == "off" || s == "false" || s == "disabled" || s == "no" || s == "0") {
    return false;
  }
  NDN_THROW(std::invalid_argument("unrecognized boolean value '" + s + "'"));
}

static FacePersistency
parseFacePersistency(const std::string& s)
{
  if (s == "persistent") {
    return FacePersistency::FACE_PERSISTENCY_PERSISTENT;
  }
  if (s == "permanent") {
    return FacePersistency::FACE_PERSISTENCY_PERMANENT;
  }
  NDN_THROW(std::invalid_argument("unrecognized FacePersistency '" + s + "'"));
}

ndn::any
CommandDefinition::parseValue(ArgValueType valueType, const std::string& token) const
{
  switch (valueType) {
    case ArgValueType::NONE:
    case ArgValueType::ANY:
      break;

    case ArgValueType::BOOLEAN:
      return parseBoolean(token);

    case ArgValueType::UNSIGNED: {
      // boost::lexical_cast<uint64_t> will accept negative number
      int64_t v = boost::lexical_cast<int64_t>(token);
      if (v < 0) {
        NDN_THROW(std::out_of_range("value '" + token + "' is negative"));
      }
      return static_cast<uint64_t>(v);
    }

    case ArgValueType::STRING:
      return token;

    case ArgValueType::REPORT_FORMAT:
      return parseReportFormat(token);

    case ArgValueType::NAME:
      return Name(token);

    case ArgValueType::FACE_URI:
      return FaceUri(token);

    case ArgValueType::FACE_ID_OR_URI:
      try {
        return boost::lexical_cast<uint64_t>(token);
      }
      catch (const boost::bad_lexical_cast&) {
        return FaceUri(token);
      }

    case ArgValueType::FACE_PERSISTENCY:
      return parseFacePersistency(token);

    case ArgValueType::ROUTE_ORIGIN:
      return boost::lexical_cast<RouteOrigin>(token);
  }

  NDN_CXX_UNREACHABLE;
}

} // namespace nfdc
} // namespace tools
} // namespace nfd
