/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2015,  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/>.
 */

#ifndef NFD_TESTS_NFD_MGMT_MANAGER_COMMON_HPP
#define NFD_TESTS_NFD_MGMT_MANAGER_COMMON_HPP

#include "tests/test-common.hpp"
#include "tests/identity-management-fixture.hpp"
#include "mgmt/manager-base.hpp"
#include "fw/forwarder.hpp"

#include <ndn-cxx/mgmt/dispatcher.hpp>
#include <ndn-cxx/util/dummy-client-face.hpp>

namespace nfd {
namespace tests {

/**
 * @brief a collection of common functions shared by all manager's testing fixtures.
 */
class ManagerCommonFixture : public UnitTestTimeFixture
                           , public IdentityManagementFixture
{
public: // initialize
  ManagerCommonFixture();

  /**
   * @brief set topPrefix to the dispatcher and configure an interest rule for the module.
   *
   * after setting @param topPrefix, call advanceClocks to ensure all added filters take effects.
   *
   * @param topPrefix top prefix for the dispatcher
   * @param privilege the module name
   */
  void
  setTopPrefixAndPrivilege(const Name& topPrefix, const std::string& privilege);

public: // test
  typedef std::function<void(shared_ptr<Interest> interest)> InterestHandler;

  /**
   * @brief create a ControlCommand request
   *
   * step1: append the @param parameters to the @param commandName and make an Interest.
   * step2: call @param beforeSinging to do something with the Interest.
   * step3: sign the generated command
   *
   * @param commandName the command name
   * @param parameters the ControlParameters
   * @param beforeSigning a callback that can modify the Interest before it's signed
   *
   * @return the signed ControlCommand request
   */
  shared_ptr<Interest>
  makeControlCommandRequest(Name commandName,
                            const ControlParameters& parameters,
                            const InterestHandler& beforeSigning = nullptr);

  /**
   * @brief cause management to receive an Interest
   *
   * call DummyClientFace::receive to receive Interest and then call advanceClocks to ensure
   * the Interest dispatched
   *
   * @param interest the Interest to receive
   */
  void
  receiveInterest(shared_ptr<Interest> interest);

public: // verify
  ControlResponse
  makeResponse(uint32_t code, const std::string& text,
               const ControlParameters& parameters);

  enum class CheckResponseResult
  {
    OK,
    OUT_OF_BOUNDARY,
    WRONG_NAME,
    WRONG_CONTENT_TYPE,
    INVALID_RESPONSE,
    WRONG_CODE,
    WRONG_TEXT,
    WRONG_BODY_SIZE,
    WRONG_BODY_VALUE
   };

  /**
   * @brief check a specified response data with the expected ControlResponse
   *
   * @param idx the index of the specified Data in m_responses
   * @param expectedDataName the expected name of this Data
   * @param expectedResponse the expected ControlResponse
   * @param expectedContentType the expected content type of this Data, use -1 to skip this check
   *
   * @retval OK the response at the specified index can be decoded from the response data,
   *            and its code, text and response body are all matched with the expected response
   * @retval OUT_OF_BOUNDARY the specified index out of boundary
   * @retval WRONG_NAME the name of the specified response data does not match
   * @retval WRONG_CONTENT_TYPE the content type of the specified response data does not match
   * @retval INVALID_RESPONSE the data name matches but it fails in decoding a ControlResponse from
   *                          the content of the specified response data
   * @retval WRONG_CODE a valid ControlResponse can be decoded but has a wrong code
   * @retval WRONG_TEXT a valid ControlResponse can be decoded but has a wrong text
   * @retval WRONG_BODY_SIZE the body size of decoded ControlResponse does not match
   * @retval WRONT_BODY_VALUE the body value of decoded ControlResponse does not match
   */
  CheckResponseResult
  checkResponse(size_t idx,
                const Name& expectedName,
                const ControlResponse& expectedResponse,
                int expectedContentType = -1);

  /**
   * @brief concatenate specified response Data into a single block
   *
   * @param startIndex the start index in m_responses
   * @param nResponses the number of response to concatenate
   *
   * @return the generated block
   */
  Block
  concatenateResponses(size_t startIndex = 0, size_t nResponses = 0);

protected:
  shared_ptr<ndn::util::DummyClientFace> m_face;
  ndn::mgmt::Dispatcher                  m_dispatcher;
  CommandValidator                       m_validator;
  Forwarder                              m_forwarder;
  std::vector<Data>&                     m_responses; // a reference of m_face->sentDatas
  Name                                   m_identityName; // the identity used to sign request
  shared_ptr<ndn::IdentityCertificate>   m_certificate; // the certificate used to sign request
};

std::ostream&
operator<<(std::ostream &os, const ManagerCommonFixture::CheckResponseResult& result);

} // namespace tests
} // namespace nfd

#endif // NFD_TESTS_NFD_MGMT_MANAGER_COMMON_HPP
