/* -*- 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.
 */

#include "validity-period.hpp"
#include "../encoding/block-helpers.hpp"
#include "../util/concepts.hpp"

namespace ndn {
namespace security {

BOOST_CONCEPT_ASSERT((boost::EqualityComparable<ValidityPeriod>));
BOOST_CONCEPT_ASSERT((WireEncodable<ValidityPeriod>));
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<ValidityPeriod>));
BOOST_CONCEPT_ASSERT((WireDecodable<ValidityPeriod>));
static_assert(std::is_base_of<tlv::Error, ValidityPeriod::Error>::value,
              "ValidityPeriod::Error must inherit from tlv::Error");

static const size_t ISO_DATETIME_SIZE = 15;
static const size_t NOT_BEFORE_OFFSET = 0;
static const size_t NOT_AFTER_OFFSET = 1;

using boost::chrono::time_point_cast;

ValidityPeriod::ValidityPeriod(const time::system_clock::TimePoint& notBefore,
                               const time::system_clock::TimePoint& notAfter)
  : m_notBefore(time_point_cast<TimePoint::duration>(notBefore + TimePoint::duration(1) -
                                                     time::system_clock::TimePoint::duration(1)))
  , m_notAfter(time_point_cast<TimePoint::duration>(notAfter))
{
}

ValidityPeriod::ValidityPeriod(const Block& block)
{
  wireDecode(block);
}

template<encoding::Tag TAG>
size_t
ValidityPeriod::wireEncode(EncodingImpl<TAG>& encoder) const
{
  size_t totalLength = 0;

  totalLength += prependStringBlock(encoder, tlv::NotAfter, time::toIsoString(m_notAfter));
  totalLength += prependStringBlock(encoder, tlv::NotBefore, time::toIsoString(m_notBefore));

  totalLength += encoder.prependVarNumber(totalLength);
  totalLength += encoder.prependVarNumber(tlv::ValidityPeriod);
  return totalLength;
}

template size_t
ValidityPeriod::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>& encoder) const;

template size_t
ValidityPeriod::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>& encoder) const;

const Block&
ValidityPeriod::wireEncode() const
{
  if (m_wire.hasWire())
    return m_wire;

  EncodingEstimator estimator;
  size_t estimatedSize = wireEncode(estimator);

  EncodingBuffer buffer(estimatedSize, 0);
  wireEncode(buffer);

  m_wire = buffer.block();
  m_wire.parse();

  return m_wire;
}

void
ValidityPeriod::wireDecode(const Block& wire)
{
  if (!wire.hasWire()) {
    throw Error("The supplied block does not contain wire format");
  }

  m_wire = wire;
  m_wire.parse();

  if (m_wire.type() != tlv::ValidityPeriod)
    throw Error("Unexpected TLV type when decoding ValidityPeriod");

  if (m_wire.elements_size() != 2)
    throw Error("Does not have two sub-TLVs");

  if (m_wire.elements()[NOT_BEFORE_OFFSET].type() != tlv::NotBefore ||
      m_wire.elements()[NOT_BEFORE_OFFSET].value_size() != ISO_DATETIME_SIZE ||
      m_wire.elements()[NOT_AFTER_OFFSET].type() != tlv::NotAfter ||
      m_wire.elements()[NOT_AFTER_OFFSET].value_size() != ISO_DATETIME_SIZE) {
    throw Error("Invalid NotBefore or NotAfter field");
  }

  try {
    m_notBefore = time_point_cast<TimePoint::duration>(
                    time::fromIsoString(readString(m_wire.elements()[NOT_BEFORE_OFFSET])));
    m_notAfter = time_point_cast<TimePoint::duration>(
                   time::fromIsoString(readString(m_wire.elements()[NOT_AFTER_OFFSET])));
  }
  catch (const std::bad_cast&) {
    throw Error("Invalid date format in NOT-BEFORE or NOT-AFTER field");
  }
}

ValidityPeriod&
ValidityPeriod::setPeriod(const time::system_clock::TimePoint& notBefore,
                          const time::system_clock::TimePoint& notAfter)
{
  m_wire.reset();
  m_notBefore = time_point_cast<TimePoint::duration>(notBefore + TimePoint::duration(1) -
                                                     time::system_clock::TimePoint::duration(1));
  m_notAfter = time_point_cast<TimePoint::duration>(notAfter);
  return *this;
}

std::pair<time::system_clock::TimePoint, time::system_clock::TimePoint>
ValidityPeriod::getPeriod() const
{
  return std::make_pair(m_notBefore, m_notAfter);
}

bool
ValidityPeriod::isValid(const time::system_clock::TimePoint& now) const
{
  return m_notBefore < now && now < m_notAfter;
}

bool
ValidityPeriod::operator==(const ValidityPeriod& other) const
{
  return (this->m_notBefore == other.m_notBefore &&
          this->m_notAfter == other.m_notAfter);
}

bool
ValidityPeriod::operator!=(const ValidityPeriod& other) const
{
  return !(*this == other);
}

std::ostream&
operator<<(std::ostream& os, const ValidityPeriod& period)
{
  os << "(" << time::toIsoString(period.getPeriod().first)
     << ", " << time::toIsoString(period.getPeriod().second) << ")";
  return os;
}

} // namespace security
} // namespace ndn
