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

#include "ndn-cxx/security/certificate-bundle-fetcher.hpp"

#include "ndn-cxx/face.hpp"
#include "ndn-cxx/security/certificate-request.hpp"
#include "ndn-cxx/security/certificate-storage.hpp"
#include "ndn-cxx/security/validation-state.hpp"
#include "ndn-cxx/util/logger.hpp"

namespace ndn {
namespace security {
inline namespace v2 {

NDN_LOG_INIT(ndn.security.CertificateBundleFetcher);

#define NDN_LOG_DEBUG_DEPTH(x) NDN_LOG_DEBUG(std::string(state->getDepth() + 1, '>') << " " << x)
#define NDN_LOG_TRACE_DEPTH(x) NDN_LOG_TRACE(std::string(state->getDepth() + 1, '>') << " " << x)

CertificateBundleFetcher::CertificateBundleFetcher(unique_ptr<CertificateFetcher> inner,
                                                   Face& face)
  : m_inner(std::move(inner))
  , m_face(face)
  , m_bundleInterestLifetime(1000)
{
  BOOST_ASSERT(m_inner != nullptr);
}

void
CertificateBundleFetcher::setBundleInterestLifetime(time::milliseconds time)
{
  m_bundleInterestLifetime = time;
}

time::milliseconds
CertificateBundleFetcher::getBundleInterestLifetime() const
{
  return m_bundleInterestLifetime;
}

void
CertificateBundleFetcher::setCertificateStorage(CertificateStorage& certStorage)
{
  m_certStorage = &certStorage;
  m_inner->setCertificateStorage(certStorage);
}

void
CertificateBundleFetcher::doFetch(const shared_ptr<CertificateRequest>& certRequest,
                                  const shared_ptr<ValidationState>& state,
                                  const ValidationContinuation& continueValidation)
{
  auto dataValidationState = dynamic_pointer_cast<DataValidationState>(state);
  if (dataValidationState == nullptr) {
    return m_inner->fetch(certRequest, state, continueValidation);
  }

  // check if a bundle segment was fetched before
  shared_ptr<BundleNameTag> bundleNameTag = state->getTag<BundleNameTag>();
  if (bundleNameTag == nullptr) {
    const Name& originalDataName = dataValidationState->getOriginalData().getName();
    if (originalDataName.empty()) {
      return m_inner->fetch(certRequest, state, continueValidation);
    }
    // derive certificate bundle name from original data name
    Name bundleNamePrefix = deriveBundleName(originalDataName);
    fetchFirstBundleSegment(bundleNamePrefix, certRequest, state, continueValidation);
  }
  else {
    Name fullBundleName = bundleNameTag->get();
    fetchNextBundleSegment(fullBundleName, fullBundleName.get(-1).getSuccessor(),
                           certRequest, state, continueValidation);
  }
}

void
CertificateBundleFetcher::fetchFirstBundleSegment(const Name& bundleNamePrefix,
                                                  const shared_ptr<CertificateRequest>& certRequest,
                                                  const shared_ptr<ValidationState>& state,
                                                  const ValidationContinuation& continueValidation)
{
  Interest bundleInterest = Interest(bundleNamePrefix);
  bundleInterest.setCanBePrefix(true);
  bundleInterest.setMustBeFresh(true);
  bundleInterest.setInterestLifetime(m_bundleInterestLifetime);

  m_face.expressInterest(bundleInterest,
                         [=] (const Interest&, const Data& data) {
                           dataCallback(data, true, certRequest, state, continueValidation);
                         },
                         [=] (const Interest&, const lp::Nack& nack) {
                           nackCallback(nack, certRequest, state, continueValidation, bundleNamePrefix);
                         },
                         [=] (const Interest&) {
                           timeoutCallback(certRequest, state, continueValidation, bundleNamePrefix);
                         });
}

void
CertificateBundleFetcher::fetchNextBundleSegment(const Name& fullBundleName, const name::Component& segmentNo,
                                                 const shared_ptr<CertificateRequest>& certRequest,
                                                 const shared_ptr<ValidationState>& state,
                                                 const ValidationContinuation& continueValidation)
{
  shared_ptr<FinalBlockIdTag> finalBlockId = state->getTag<FinalBlockIdTag>();
  if (finalBlockId != nullptr && segmentNo > finalBlockId->get()) {
    return m_inner->fetch(certRequest, state, continueValidation);
  }

  Interest bundleInterest(fullBundleName.getPrefix(-1).append(segmentNo));
  bundleInterest.setCanBePrefix(false);
  bundleInterest.setMustBeFresh(false);
  bundleInterest.setInterestLifetime(m_bundleInterestLifetime);

  m_face.expressInterest(bundleInterest,
                         [=] (const Interest&, const Data& data) {
                           dataCallback(data, false, certRequest, state, continueValidation);
                         },
                         [=] (const Interest&, const lp::Nack& nack) {
                           nackCallback(nack, certRequest, state, continueValidation, fullBundleName);
                         },
                         [=] (const Interest&) {
                           timeoutCallback(certRequest, state, continueValidation, fullBundleName);
                         });
}

void
CertificateBundleFetcher::dataCallback(const Data& bundleData,
                                       bool isSegmentZeroExpected,
                                       const shared_ptr<CertificateRequest>& certRequest,
                                       const shared_ptr<ValidationState>& state,
                                       const ValidationContinuation& continueValidation)
{
  NDN_LOG_DEBUG_DEPTH("Fetched certificate bundle from network " << bundleData.getName());

  name::Component currentSegment = bundleData.getName().get(-1);
  if (!currentSegment.isSegment()) {
    return m_inner->fetch(certRequest, state, continueValidation);
  }

  if (isSegmentZeroExpected && currentSegment.toSegment() != 0) {
    // fetch segment zero
    fetchNextBundleSegment(bundleData.getName(), name::Component::fromSegment(0),
                           certRequest, state, continueValidation);
  }
  else {
    state->setTag(make_shared<BundleNameTag>(bundleData.getName()));

    const auto& finalBlockId = bundleData.getFinalBlock();
    if (finalBlockId) {
      state->setTag(make_shared<FinalBlockIdTag>(*finalBlockId));
    }

    Block bundleContent = bundleData.getContent();
    bundleContent.parse();

    // store all the certificates in unverified cache
    for (const auto& block : bundleContent.elements()) {
      m_certStorage->cacheUnverifiedCert(Certificate(block));
    }

    auto cert = m_certStorage->getUnverifiedCertCache().find(certRequest->interest);
    continueValidation(*cert, state);
  }
}

void
CertificateBundleFetcher::nackCallback(const lp::Nack& nack,
                                       const shared_ptr<CertificateRequest>& certRequest,
                                       const shared_ptr<ValidationState>& state,
                                       const ValidationContinuation& continueValidation,
                                       const Name& bundleName)
{
  NDN_LOG_DEBUG_DEPTH("NACK (" << nack.getReason() <<  ") while fetching certificate bundle"
                      << bundleName);

  m_inner->fetch(certRequest, state, continueValidation);
}

void
CertificateBundleFetcher::timeoutCallback(const shared_ptr<CertificateRequest>& certRequest,
                                          const shared_ptr<ValidationState>& state,
                                          const ValidationContinuation& continueValidation,
                                          const Name& bundleName)
{
  NDN_LOG_DEBUG_DEPTH("Timeout while fetching certificate bundle" << bundleName);

  m_inner->fetch(certRequest, state, continueValidation);
}

Name
CertificateBundleFetcher::deriveBundleName(const Name& name)
{
  name::Component lastComponent = name.at(-1);

  Name bundleName = name;
  if (lastComponent.isImplicitSha256Digest()) {
    if (name.size() >= 2 && name.get(-2).isSegment()) {
      bundleName = name.getPrefix(-2);
    }
    else {
      bundleName = name.getPrefix(-1);
    }
  }
  else if (lastComponent.isSegment()) {
    bundleName = name.getPrefix(-1);
  }
  bundleName.append("_BUNDLE");
  bundleName.appendNumber(0);

  return bundleName;
}

} // inline namespace v2
} // namespace security
} // namespace ndn
