/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2017 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 "certificate-cache.hpp"
#include "util/logger.hpp"

namespace ndn {
namespace security {
namespace v2 {

NDN_LOG_INIT(ndn.security.v2.CertificateCache);

const time::nanoseconds&
CertificateCache::getDefaultLifetime()
{
  static time::nanoseconds lifetime = time::seconds(3600);
  return lifetime;
}

CertificateCache::CertificateCache(const time::nanoseconds& maxLifetime)
  : m_certsByTime(m_certs.get<0>())
  , m_certsByName(m_certs.get<1>())
  , m_maxLifetime(maxLifetime)
{
}

void
CertificateCache::insert(const Certificate& cert)
{
  time::system_clock::TimePoint notAfterTime = cert.getValidityPeriod().getPeriod().second;
  time::system_clock::TimePoint now = time::system_clock::now();
  if (notAfterTime < now) {
    NDN_LOG_DEBUG("Not adding " << cert.getName() << ": already expired at " << time::toIsoString(notAfterTime));
    return;
  }

  time::system_clock::TimePoint removalTime = std::min(notAfterTime, now + m_maxLifetime);
  NDN_LOG_DEBUG("Adding " << cert.getName() << ", will remove in "
                << time::duration_cast<time::seconds>(removalTime - now));
  m_certs.insert(Entry(cert, removalTime));
}

const Certificate*
CertificateCache::find(const Name& keyName)
{
  refresh();
  if (keyName.size() > 0 && keyName[-1].isImplicitSha256Digest()) {
    NDN_LOG_INFO("Certificate search using name with the implicit digest is not yet supported");
  }
  auto itr = m_certsByName.lower_bound(keyName);
  if (itr == m_certsByName.end() || !keyName.isPrefixOf(itr->getCertName()))
    return nullptr;
  return &itr->cert;
}

const Certificate*
CertificateCache::find(const Interest& interest)
{
  if (interest.getChildSelector() >= 0) {
    NDN_LOG_DEBUG("Certificate search using ChildSelector is not supported, search as if selector not specified");
  }
  if (interest.getName().size() > 0 && interest.getName()[-1].isImplicitSha256Digest()) {
    NDN_LOG_INFO("Certificate search using name with the implicit digest is not yet supported");
  }
  refresh();

  for (auto i = m_certsByName.lower_bound(interest.getName());
       i != m_certsByName.end() && interest.getName().isPrefixOf(i->getCertName());
       ++i) {
    const auto& cert = i->cert;
    if (interest.matchesData(cert)) {
      return &cert;
    }
  }
  return nullptr;
}

void
CertificateCache::refresh()
{
  time::system_clock::TimePoint now = time::system_clock::now();

  auto cIt = m_certsByTime.begin();
  while (cIt != m_certsByTime.end() && cIt->removalTime < now) {
    m_certsByTime.erase(cIt);
    cIt = m_certsByTime.begin();
  }
}

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