/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2015 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#ifndef NDN_UTIL_SEGMENT_FETCHER_HPP
#define NDN_UTIL_SEGMENT_FETCHER_HPP

#include "scheduler.hpp"
#include "../common.hpp"
#include "../face.hpp"
#include "../security/validator.hpp"

namespace ndn {

class OBufferStream;

namespace util {

/**
 * @brief Utility class to fetch latest version of the segmented data
 *
 * SegmentFetcher assumes that the data is named `/<prefix>/<version>/<segment>`,
 * where:
 * - `<prefix>` is the specified prefix,
 * - `<version>` is an unknown version that needs to be discovered, and
 * - `<segment>` is a segment number (number of segments is unknown and is controlled
 *   by `FinalBlockId` field in at least the last Data packet
 *
 * The following logic is implemented in SegmentFetcher:
 *
 * 1. Express first interest to discover version:
 *
 *    >> Interest: `/<prefix>?ChildSelector=1&MustBeFresh=yes`
 *
 * 2. Infer the latest version of Data:  `<version> = Data.getName().get(-2)`
 *
 * 3. If segment number in the retrieved packet == 0, go to step 5.
 *
 * 4. Send Interest for segment 0:
 *
 *    >> Interest: `/<prefix>/<version>/<segment=0>`
 *
 * 5. Keep sending Interests for the next segment while the retrieved Data does not have
 *    FinalBlockId or FinalBlockId != Data.getName().get(-1).
 *
 *    >> Interest: `/<prefix>/<version>/<segment=(N+1))>`
 *
 * 6. Fire onCompletion callback with memory block that combines content part from all
 *    segmented objects.
 *
 * If an error occurs during the fetching process, an error callback is fired
 * with a proper error code.  The following errors are possible:
 *
 * - `INTEREST_TIMEOUT`: if any of the Interests times out
 * - `DATA_HAS_NO_SEGMENT`: if any of the retrieved Data packets don't have segment
 *   as a last component of the name (not counting implicit digest)
 * - `SEGMENT_VALIDATION_FAIL`: if any retrieved segment fails user-provided validation
 *
 * In order to validate individual segments, a Validator instance needs to be specified.
 * If the segment validation is successful, afterValidationSuccess callback is fired, otherwise
 * afterValidationFailure callback.
 *
 * Examples:
 *
 *     void
 *     afterFetchComplete(const ConstBufferPtr& data)
 *     {
 *       ...
 *     }
 *
 *     void
 *     afterFetchError(uint32_t errorCode, const std::string& errorMsg)
 *     {
 *       ...
 *     }
 *
 *     ...
 *     SegmentFetcher::fetch(face, Interest("/data/prefix", time::seconds(1000)),
 *                           validator,
 *                           bind(&afterFetchComplete, this, _1),
 *                           bind(&afterFetchError, this, _1, _2));
 *
 */
class SegmentFetcher : noncopyable
{
public:
  /**
   * @brief Maximum number of times an interest will be reexpressed incase of NackCallback
   */
  static const uint32_t MAX_INTEREST_REEXPRESS;

  typedef function<void (const ConstBufferPtr& data)> CompleteCallback;
  typedef function<void (uint32_t code, const std::string& msg)> ErrorCallback;

  /**
   * @brief Error codes that can be passed to ErrorCallback
   */
  enum ErrorCode {
    INTEREST_TIMEOUT = 1,
    DATA_HAS_NO_SEGMENT = 2,
    SEGMENT_VALIDATION_FAIL = 3,
    NACK_ERROR = 4
  };

  /**
   * @brief Initiate segment fetching
   *
   * @param face          Reference to the Face that should be used to fetch data
   * @param baseInterest  An Interest for the initial segment of requested data.
   *                      This interest may include custom InterestLifetime and selectors that
   *                      will propagate to all subsequent Interests.  The only exception is that
   *                      the initial Interest will be forced to include "ChildSelector=rightmost" and
   *                      "MustBeFresh=true" selectors, which will be turned off in subsequent
   *                      Interests.
   * @param validator     Reference to the Validator that should be used to validate data. Caller
   *                      must ensure validator is valid until either completeCallback or errorCallback
   *                      is invoked.
   *
   * @param completeCallback    Callback to be fired when all segments are fetched
   * @param errorCallback       Callback to be fired when an error occurs (@see Errors)
   */
  static
  void
  fetch(Face& face,
        const Interest& baseInterest,
        Validator& validator,
        const CompleteCallback& completeCallback,
        const ErrorCallback& errorCallback);

  /**
   * @brief Initiate segment fetching
   *
   * @param face          Reference to the Face that should be used to fetch data
   * @param baseInterest  An Interest for the initial segment of requested data.
   *                      This interest may include custom InterestLifetime and selectors that
   *                      will propagate to all subsequent Interests.  The only exception is that
   *                      the initial Interest will be forced to include "ChildSelector=1" and
   *                      "MustBeFresh=true" selectors, which will be turned off in subsequent
   *                      Interests.
   * @param validator     A shared_ptr to the Validator that should be used to validate data.
   *
   * @param completeCallback    Callback to be fired when all segments are fetched
   * @param errorCallback       Callback to be fired when an error occurs (@see Errors)
   */
  static
  void
  fetch(Face& face,
        const Interest& baseInterest,
        shared_ptr<Validator> validator,
        const CompleteCallback& completeCallback,
        const ErrorCallback& errorCallback);

private:
  SegmentFetcher(Face& face,
                 shared_ptr<Validator> validator,
                 const CompleteCallback& completeCallback,
                 const ErrorCallback& errorCallback);

  void
  fetchFirstSegment(const Interest& baseInterest, shared_ptr<SegmentFetcher> self);

  void
  fetchNextSegment(const Interest& origInterest, const Name& dataName, uint64_t segmentNo,
                   shared_ptr<SegmentFetcher> self);

  void
  afterSegmentReceived(const Interest& origInterest,
                       const Data& data, bool isSegmentZeroExpected,
                       shared_ptr<SegmentFetcher> self);
  void
  afterValidationSuccess(const shared_ptr<const Data> data,
                         bool isSegmentZeroExpected,
                         const Interest& origInterest,
                         shared_ptr<SegmentFetcher> self);

  void
  afterValidationFailure(const shared_ptr<const Data> data);

  void
  afterNackReceived(const Interest& origInterest, const lp::Nack& nack,
                    uint32_t reExpressCount, shared_ptr<SegmentFetcher> self);

  void
  reExpressInterest(Interest interest, uint32_t reExpressCount,
                    shared_ptr<SegmentFetcher> self);

private:
  Face& m_face;
  Scheduler m_scheduler;
  shared_ptr<Validator> m_validator;
  CompleteCallback m_completeCallback;
  ErrorCallback m_errorCallback;

  shared_ptr<OBufferStream> m_buffer;
};

} // namespace util
} // namespace ndn

#endif // NDN_UTIL_SEGMENT_FETCHER_HPP
