/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (c) 2013-2014,  Regents of the University of California.
 * All rights reserved.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 *
 * This file licensed under New BSD License.  See COPYING for detailed information about
 * ndn-cxx library copyright, permissions, and redistribution restrictions.
 */

#ifndef NDN_MANAGEMENT_NFD_CONTROL_COMMAND_HPP
#define NDN_MANAGEMENT_NFD_CONTROL_COMMAND_HPP

#include "nfd-control-parameters.hpp"
#include "../util/command-interest-generator.hpp"

namespace ndn {
namespace nfd {

/** \brief base class of NFD ControlCommand
 *  \sa http://redmine.named-data.net/projects/nfd/wiki/ControlCommand
 */
class ControlCommand : noncopyable
{
public:
  /** \brief represents an error in ControlParameters
   */
  class ArgumentError : public std::invalid_argument
  {
  public:
    explicit
    ArgumentError(const std::string& what)
      : std::invalid_argument(what)
    {
    }
  };

  /** \return Name prefix of this ControlCommand
   */
  const Name&
  getPrefix() const
  {
    return m_prefix;
  }

  /** \brief make a Command Interest from parameters
   */
  Interest
  makeCommandInterest(const ControlParameters& parameters,
                      CommandInterestGenerator& commandInterestGenerator) const
  {
    this->validateRequest(parameters);

    Name name = m_prefix;
    name.append(parameters.wireEncode());
    Interest commandInterest(name);
    commandInterestGenerator.generate(commandInterest);
    return commandInterest;
  }

  /** \brief validate request parameters
   *  \throw ArgumentError
   */
  virtual void
  validateRequest(const ControlParameters& parameters) const
  {
    m_requestValidator.validate(parameters);
  }

  /** \brief apply default values to missing fields in request
   */
  virtual void
  applyDefaultsToRequest(ControlParameters& parameters) const
  {
  }

  /** \brief validate response parameters
   *  \throw ArgumentError
   */
  virtual void
  validateResponse(const ControlParameters& parameters) const
  {
    m_responseValidator.validate(parameters);
  }

  /** \brief apply default values to missing fields in response
   */
  virtual void
  applyDefaultsToResponse(ControlParameters& parameters) const
  {
  }

protected:
  ControlCommand(const std::string& module, const std::string& verb)
    : m_prefix("ndn:/localhost/nfd")
  {
    m_prefix.append(module).append(verb);
  }

  class FieldValidator
  {
  public:
    FieldValidator()
      : m_required(CONTROL_PARAMETER_UBOUND)
      , m_optional(CONTROL_PARAMETER_UBOUND)
    {
    }

    /** \brief declare a required field
     */
    FieldValidator&
    required(ControlParameterField field)
    {
      m_required[field] = true;
      return *this;
    }

    /** \brief declare an optional field
     */
    FieldValidator&
    optional(ControlParameterField field)
    {
      m_optional[field] = true;
      return *this;
    }

    /** \brief verify that all required fields are present,
     *         and all present fields are either required or optional
     *  \throw ArgumentError
     */
    void
    validate(const ControlParameters& parameters) const
    {
      const std::vector<bool>& presentFields = parameters.getPresentFields();

      for (size_t i = 0; i < CONTROL_PARAMETER_UBOUND; ++i) {
        bool isPresent = presentFields[i];
        if (m_required[i]) {
          if (!isPresent) {
            throw ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is required but missing");
          }
        }
        else if (isPresent && !m_optional[i]) {
          throw ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is forbidden but present");
        }
      }
    }

  private:
    std::vector<bool> m_required;
    std::vector<bool> m_optional;
  };

protected:
  /** \brief FieldValidator for request ControlParameters
   *
   *  Constructor of subclass should populate this validator.
   */
  FieldValidator m_requestValidator;
  /** \brief FieldValidator for response ControlParameters
   *
   *  Constructor of subclass should populate this validator.
   */
  FieldValidator m_responseValidator;

private:
  Name m_prefix;
};


/** \brief represents a faces/create command
 *  \sa http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Create-a-face
 */
class FaceCreateCommand : public ControlCommand
{
public:
  FaceCreateCommand()
    : ControlCommand("faces", "create")
  {
    m_requestValidator
      .required(CONTROL_PARAMETER_URI);
    m_responseValidator
      .required(CONTROL_PARAMETER_URI)
      .required(CONTROL_PARAMETER_FACE_ID);
  }

  virtual void
  validateResponse(const ControlParameters& parameters) const
  {
    this->ControlCommand::validateResponse(parameters);

    if (parameters.getFaceId() == 0) {
      throw ArgumentError("FaceId must not be zero");
    }
  }
};


/** \brief represents a faces/destroy command
 *  \sa http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Destroy-a-face
 */
class FaceDestroyCommand : public ControlCommand
{
public:
  FaceDestroyCommand()
    : ControlCommand("faces", "destroy")
  {
    m_requestValidator
      .required(CONTROL_PARAMETER_FACE_ID);
    m_responseValidator = m_requestValidator;
  }

  virtual void
  validateRequest(const ControlParameters& parameters) const
  {
    this->ControlCommand::validateRequest(parameters);

    if (parameters.getFaceId() == 0) {
      throw ArgumentError("FaceId must not be zero");
    }
  }

  virtual void
  validateResponse(const ControlParameters& parameters) const
  {
    this->validateRequest(parameters);
  }
};


class FaceLocalControlCommand : public ControlCommand
{
public:
  virtual void
  validateRequest(const ControlParameters& parameters) const
  {
    this->ControlCommand::validateRequest(parameters);

    switch (parameters.getLocalControlFeature()) {
      case LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID:
      case LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID:
        break;
      default:
        throw ArgumentError("LocalControlFeature is invalid");
    }
  }

  virtual void
  validateResponse(const ControlParameters& parameters) const
  {
    this->validateRequest(parameters);
  }

protected:
  explicit
  FaceLocalControlCommand(const std::string& verb)
    : ControlCommand("faces", verb)
  {
    m_requestValidator
      .required(CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE);
    m_responseValidator = m_requestValidator;
  }
};


/** \brief represents a faces/enable-local-control command
 *  \sa http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Enable-a-LocalControlHeader-feature
 */
class FaceEnableLocalControlCommand : public FaceLocalControlCommand
{
public:
  FaceEnableLocalControlCommand()
    : FaceLocalControlCommand("enable-local-control")
  {
  }
};


/** \brief represents a faces/disable-local-control command
 *  \sa http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Disable-a-LocalControlHeader-feature
 */
class FaceDisableLocalControlCommand : public FaceLocalControlCommand
{
public:
  FaceDisableLocalControlCommand()
    : FaceLocalControlCommand("disable-local-control")
  {
  }
};


/** \brief represents a fib/add-nexthop command
 *  \sa http://redmine.named-data.net/projects/nfd/wiki/FibMgmt#Add-a-nexthop
 */
class FibAddNextHopCommand : public ControlCommand
{
public:
  FibAddNextHopCommand()
    : ControlCommand("fib", "add-nexthop")
  {
    m_requestValidator
      .required(CONTROL_PARAMETER_NAME)
      .required(CONTROL_PARAMETER_FACE_ID)
      .optional(CONTROL_PARAMETER_COST);
    m_responseValidator
      .required(CONTROL_PARAMETER_NAME)
      .required(CONTROL_PARAMETER_FACE_ID)
      .required(CONTROL_PARAMETER_COST);
  }

  virtual void
  applyDefaultsToRequest(ControlParameters& parameters) const
  {
    if (!parameters.hasCost()) {
      parameters.setCost(0);
    }
  }

  virtual void
  validateResponse(const ControlParameters& parameters) const
  {
    this->ControlCommand::validateResponse(parameters);

    if (parameters.getFaceId() == 0) {
      throw ArgumentError("FaceId must not be zero");
    }
  }
};


/** \brief represents a fib/remove-nexthop command
 *  \sa http://redmine.named-data.net/projects/nfd/wiki/FibMgmt#Remove-a-nexthop
 */
class FibRemoveNextHopCommand : public ControlCommand
{
public:
  FibRemoveNextHopCommand()
    : ControlCommand("fib", "remove-nexthop")
  {
    m_requestValidator
      .required(CONTROL_PARAMETER_NAME)
      .required(CONTROL_PARAMETER_FACE_ID);
    m_responseValidator
      .required(CONTROL_PARAMETER_NAME)
      .required(CONTROL_PARAMETER_FACE_ID);
  }

  virtual void
  validateResponse(const ControlParameters& parameters) const
  {
    this->ControlCommand::validateResponse(parameters);

    if (parameters.getFaceId() == 0) {
      throw ArgumentError("FaceId must not be zero");
    }
  }
};


/** \brief represents a strategy-choice/set command
 *  \sa http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice#Set-the-strategy-for-a-namespace
 */
class StrategyChoiceSetCommand : public ControlCommand
{
public:
  StrategyChoiceSetCommand()
    : ControlCommand("strategy-choice", "set")
  {
    m_requestValidator
      .required(CONTROL_PARAMETER_NAME)
      .required(CONTROL_PARAMETER_STRATEGY);
    m_responseValidator = m_requestValidator;
  }
};


/** \brief represents a strategy-choice/set command
 *  \sa http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice#Unset-the-strategy-for-a-namespace
 */
class StrategyChoiceUnsetCommand : public ControlCommand
{
public:
  StrategyChoiceUnsetCommand()
    : ControlCommand("strategy-choice", "unset")
  {
    m_requestValidator
      .required(CONTROL_PARAMETER_NAME);
    m_responseValidator = m_requestValidator;
  }

  virtual void
  validateRequest(const ControlParameters& parameters) const
  {
    this->ControlCommand::validateRequest(parameters);

    if (parameters.getName().size() == 0) {
      throw ArgumentError("Name must not be ndn:/");
    }
  }

  virtual void
  validateResponse(const ControlParameters& parameters) const
  {
    this->validateRequest(parameters);
  }
};


enum {
  // route origin
  ROUTE_ORIGIN_APP    = 0,
  ROUTE_ORIGIN_NLSR   = 128,
  ROUTE_ORIGIN_STATIC = 255,

  // route inheritance flags
  ROUTE_FLAG_CHILD_INHERIT = 1,
  ROUTE_FLAG_CAPTURE       = 2
};


/** \brief represents a rib/register command
 *  \sa http://redmine.named-data.net/projects/nfd/wiki/RibMgmt#Register-a-route
 */
class RibRegisterCommand : public ControlCommand
{
public:
  RibRegisterCommand()
    : ControlCommand("rib", "register")
  {
    m_requestValidator
      .required(CONTROL_PARAMETER_NAME)
      .optional(CONTROL_PARAMETER_FACE_ID)
      .optional(CONTROL_PARAMETER_ORIGIN)
      .optional(CONTROL_PARAMETER_COST)
      .optional(CONTROL_PARAMETER_FLAGS)
      .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
    m_responseValidator
      .required(CONTROL_PARAMETER_NAME)
      .required(CONTROL_PARAMETER_FACE_ID)
      .required(CONTROL_PARAMETER_ORIGIN)
      .required(CONTROL_PARAMETER_COST)
      .required(CONTROL_PARAMETER_FLAGS)
      .required(CONTROL_PARAMETER_EXPIRATION_PERIOD);
  }

  virtual void
  applyDefaultsToRequest(ControlParameters& parameters) const
  {
    if (!parameters.hasFaceId()) {
      parameters.setFaceId(0);
    }
    if (!parameters.hasOrigin()) {
      parameters.setOrigin(ROUTE_ORIGIN_APP);
    }
    if (!parameters.hasCost()) {
      parameters.setCost(0);
    }
    if (!parameters.hasFlags()) {
      parameters.setFlags(ROUTE_FLAG_CHILD_INHERIT);
    }
    if (!parameters.hasExpirationPeriod()) {
      if (parameters.getFaceId() == 0) {
        parameters.setExpirationPeriod(time::milliseconds::max());
      }
      else {
        parameters.setExpirationPeriod(time::hours(1));
      }
    }
  }

  virtual void
  validateResponse(const ControlParameters& parameters) const
  {
    this->ControlCommand::validateResponse(parameters);

    if (parameters.getFaceId() == 0) {
      throw ArgumentError("FaceId must not be zero");
    }
  }
};


/** \brief represents a rib/unregister command
 *  \sa http://redmine.named-data.net/projects/nfd/wiki/RibMgmt#Unregister-a-route
 */
class RibUnregisterCommand : public ControlCommand
{
public:
  RibUnregisterCommand()
    : ControlCommand("rib", "unregister")
  {
    m_requestValidator
      .required(CONTROL_PARAMETER_NAME)
      .optional(CONTROL_PARAMETER_FACE_ID)
      .optional(CONTROL_PARAMETER_ORIGIN);
    m_responseValidator
      .required(CONTROL_PARAMETER_NAME)
      .required(CONTROL_PARAMETER_FACE_ID)
      .required(CONTROL_PARAMETER_ORIGIN);
  }

  virtual void
  applyDefaultsToRequest(ControlParameters& parameters) const
  {
    if (!parameters.hasFaceId()) {
      parameters.setFaceId(0);
    }
    if (!parameters.hasOrigin()) {
      parameters.setOrigin(ROUTE_ORIGIN_APP);
    }
  }

  virtual void
  validateResponse(const ControlParameters& parameters) const
  {
    this->ControlCommand::validateResponse(parameters);

    if (parameters.getFaceId() == 0) {
      throw ArgumentError("FaceId must not be zero");
    }
  }
};


} // namespace nfd
} // namespace ndn

#endif // NDN_MANAGEMENT_NFD_CONTROL_COMMAND_HPP
