/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014, Regents of the University of California.
 *
 * This file is part of NDNS (Named Data Networking Domain Name Service).
 * See AUTHORS.md for complete list of NDNS authors and contributors.
 *
 * NDNS 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.
 *
 * NDNS 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
 * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef NDNS_CLIENTS_ITERATIVE_QUERY_CONTROLLER_HPP
#define NDNS_CLIENTS_ITERATIVE_QUERY_CONTROLLER_HPP

#include "ndns-enum.hpp"
#include "query.hpp"
#include "response.hpp"
#include "query-controller.hpp"
#include "config.hpp"
#include "common.hpp"
#include "validator.hpp"

#include <ndn-cxx/common.hpp>
#include <ndn-cxx/data.hpp>
#include <ndn-cxx/interest.hpp>
#include <ndn-cxx/name.hpp>

namespace ndn {
namespace ndns {

/**
 * @brief controller which iteratively query a target label
 */
class IterativeQueryController : public QueryController
{
public:
  /**
   * @brief indicates a step in an iterative query process.
   * Iterative Query contains multiple steps which are listed here
   */
  enum QueryStep {
    QUERY_STEP_QUERY_NS = 1, ///< to query the naming server, before querying NS & waiting for Data
    QUERY_STEP_QUERY_RR, ///< to query RR, before querying RR & waiting for it Data
    QUERY_STEP_ANSWER_STUB, ///< to answer to stub resolver, after getting final Response,
                            ///< or NACK or timeout
    QUERY_STEP_ABORT, ///< to abort the resolver process, if unexpected behavior happens
    QUERY_STEP_UNKNOWN = 255
  };

public:
  explicit
  IterativeQueryController(const Name& dstLabel, const name::Component& rrType,
                           const time::milliseconds& interestLifetime,
                           const QuerySucceedCallback& onSucceed, const QueryFailCallback& onFail,
                           Face& face, Validator* validator = nullptr);

  virtual void
  start();

  /**
   * @brief return false if the current status is not QUEYR_STEP_QUERY_NS
   * or QUERY_STEP_QUERY_RR
   */
  virtual bool
  hasEnded();

NDNS_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  void
  onData(const ndn::Interest& interest, const Data& data);

  void
  onDataValidated(const shared_ptr<const Data>& data, NdnsType ndnsType);

  /**
   * @brief change the Controller state according to timeout. For current,
   * abort the query when timeout
   */
  void
  onTimeout(const Interest& interest);

  void
  abort();

  /**
   * @brief get the Interest according to current Controller state.
   * Only be valid on State QueryNS & QueryRR, or throw exception
   */
  const Interest
  makeLatestInterest();

  const Response
  parseFinalResponse(const Data& data);

  void
  express(const Interest& interest);

public:
  void
  setStartComponentIndex(size_t finished)
  {
    m_nFinishedComps = finished;
  }

  QueryStep
  getStep() const
  {
    return m_step;
  }

  size_t
  getNFinishedComps() const
  {
    return m_nFinishedComps;
  }

  size_t
  getNTryComps() const
  {
    return m_nTryComps;
  }

protected:
  Validator* m_validator;
  /**
   * @brief current query step
   */
  QueryStep m_step;

  /*
   * the number of label that has been resolved successfully
   * This also define the next AuthZone prefix
   * AuthZone = m_query.getRrLabel().getPrefix(m_nFinishedComps)
   */
  size_t m_nFinishedComps;

  /*
   * used when query the KSK (key signing key), e.g., /net/ndnsim/ksk-1
   */
  size_t m_nTryComps;
};

std::ostream&
operator<<(std::ostream& os, const IterativeQueryController& iq);

std::ostream&
operator<<(std::ostream& os, const IterativeQueryController::QueryStep step);

} // namespace ndns
} // namespace ndn

#endif // NDNS_CLIENTS_ITERATIVE_QUERY_HPP
