/* -*- 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()) {
    BOOST_THROW_EXCEPTION(Error("The supplied block does not contain wire format"));
  }

  m_wire = wire;
  m_wire.parse();

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

  if (m_wire.elements_size() != 2)
    BOOST_THROW_EXCEPTION(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) {
    BOOST_THROW_EXCEPTION(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&) {
    BOOST_THROW_EXCEPTION(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
