/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2011 University of California, Los Angeles
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
 *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#include "../ccnb.h"

#include "wire-ccnb.h"

#include "ns3/log.h"

#include "ccnb-parser/common.h"
#include "ccnb-parser/visitors/void-depth-first-visitor.h"
#include "ccnb-parser/visitors/name-visitor.h"
#include "ccnb-parser/visitors/non-negative-integer-visitor.h"
#include "ccnb-parser/visitors/timestamp-visitor.h"
#include "ccnb-parser/visitors/string-visitor.h"
#include "ccnb-parser/visitors/uint32t-blob-visitor.h"
#include "ccnb-parser/visitors/content-type-visitor.h"

#include "ccnb-parser/syntax-tree/block.h"
#include "ccnb-parser/syntax-tree/dtag.h"

#include <boost/foreach.hpp>

NS_LOG_COMPONENT_DEFINE ("ndn.wire.Ccnb.Data");

NDN_NAMESPACE_BEGIN

namespace wire {
namespace ccnb {

// const std::string DefaultDigestAlgorithm = "2.16.840.1.101.3.4.2.1";

class DataTrailer : public Trailer
{
public:
  DataTrailer ()
  {
  }

  static TypeId GetTypeId ()
  {
    static TypeId tid = TypeId ("ns3::ndn::Data::Ccnb::Closer")
      .SetGroupName ("Ndn")
      .SetParent<Trailer> ()
      .AddConstructor<DataTrailer> ()
      ;
    return tid;
  }

  virtual TypeId GetInstanceTypeId (void) const
  {
    return GetTypeId ();
  }

  virtual void Print (std::ostream &os) const
  {
  }

  virtual uint32_t GetSerializedSize (void) const
  {
    return 2;
  }

  virtual void Serialize (Buffer::Iterator end) const
  {
    Buffer::Iterator i = end;
    i.Prev (2); // Trailer interface requires us to go backwards

    i.WriteU8 (0x00); // </Content>
    i.WriteU8 (0x00); // </ContentObject>
  }

  virtual uint32_t Deserialize (Buffer::Iterator end)
  {
    Buffer::Iterator i = end;
    i.Prev (2); // Trailer interface requires us to go backwards

    uint8_t closing_tag_content = i.ReadU8 ();
    NS_ASSERT_MSG (closing_tag_content==0, "Should be a closing tag </Content> (0x00)");

    uint8_t closing_tag_content_object = i.ReadU8 ();
    NS_ASSERT_MSG (closing_tag_content_object==0, "Should be a closing tag </ContentObject> (0x00)");

    return 2;
  }
};

NS_OBJECT_ENSURE_REGISTERED (Data);
NS_OBJECT_ENSURE_REGISTERED (DataTrailer);

TypeId
Data::GetTypeId (void)
{
  static TypeId tid = TypeId ("ns3::ndn::Data::Ccnb")
    .SetGroupName ("Ndn")
    .SetParent<Header> ()
    .AddConstructor<Data> ()
    ;
  return tid;
}

TypeId
Data::GetInstanceTypeId (void) const
{
  return GetTypeId ();
}

Data::Data ()
  : m_data (Create<ndn::ContentObject> ())
{
}

Data::Data (Ptr<ndn::ContentObject> data)
  : m_data (data)
{
}

Ptr<ndn::ContentObject>
Data::GetData ()
{
  return m_data;
}

Ptr<Packet>
Data::ToWire (Ptr<const ndn::ContentObject> data)
{
  static DataTrailer trailer;

  Ptr<const Packet> p = data->GetWire ();
  if (!p)
    {
      Ptr<Packet> packet = Create<Packet> (*data->GetPayload ());
      Data wireEncoding (ConstCast<ndn::ContentObject> (data));
      packet->AddHeader (wireEncoding);
      packet->AddTrailer (trailer);
      data->SetWire (packet);

      p = packet;
    }

  return p->Copy ();
}

Ptr<ndn::ContentObject>
Data::FromWire (Ptr<Packet> packet)
{
  static DataTrailer trailer;

  Ptr<ndn::ContentObject> data = Create<ndn::ContentObject> ();
  data->SetWire (packet->Copy ());

  Data wireEncoding (data);
  packet->RemoveHeader (wireEncoding);
  packet->RemoveTrailer (trailer);

  data->SetPayload (packet);

  return data;
}

void
Data::Serialize (Buffer::Iterator start) const
{
  Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_ContentObject, CcnbParser::CCN_DTAG); // <ContentObject>

  // fake signature
  Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Signature, CcnbParser::CCN_DTAG); // <Signature>
  // Signature ::= √DigestAlgorithm?
  //               Witness?
  //               √SignatureBits
  // if (GetSignature ().GetDigestAlgorithm () != Signature::DefaultDigestAlgorithm)
  //   {
  //     Ccnb::AppendString (start, CcnbParser::CCN_DTAG_DigestAlgorithm, GetSignature ().GetDigestAlgorithm ());
  //   }
  Ccnb::AppendTaggedBlob (start, CcnbParser::CCN_DTAG_SignatureBits, m_data->GetSignature ()); // <SignatureBits />
  Ccnb::AppendCloser (start);                                    // </Signature>

  Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Name, CcnbParser::CCN_DTAG);    // <Name>
  Ccnb::SerializeName (start, m_data->GetName());                                      //   <Component>...</Component>...
  Ccnb::AppendCloser (start);                                                          // </Name>

  // fake signature
  Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_SignedInfo, CcnbParser::CCN_DTAG); // <SignedInfo>
  // SignedInfo ::= √PublisherPublicKeyDigest
  //                √Timestamp
  //                √Type?
  //                √FreshnessSeconds?
  //                FinalBlockID?
  //                KeyLocator?
  // Ccnb::AppendTaggedBlob (start, CcnbParser::CCN_DTAG_PublisherPublicKeyDigest,         // <PublisherPublicKeyDigest>...
  //                         GetSignedInfo ().GetPublisherPublicKeyDigest ());

  Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Timestamp, CcnbParser::CCN_DTAG);            // <Timestamp>...
  Ccnb::AppendTimestampBlob (start, m_data->GetTimestamp ());
  Ccnb::AppendCloser (start);

  // if (GetSignedInfo ().GetContentType () != DATA)
  //   {
  //     uint8_t type[3];
  //     type[0] = (GetSignedInfo ().GetContentType () >> 16) & 0xFF;
  //     type[1] = (GetSignedInfo ().GetContentType () >> 8 ) & 0xFF;
  //     type[2] = (GetSignedInfo ().GetContentType ()      ) & 0xFF;

  //     Ccnb::AppendTaggedBlob (start, CCN_DTAG_Type, type, 3);
  //   }
  if (m_data->GetFreshness () > Seconds(0))
    {
      Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_FreshnessSeconds, CcnbParser::CCN_DTAG);
      Ccnb::AppendNumber (start, m_data->GetFreshness ().ToInteger (Time::S));
      Ccnb::AppendCloser (start);
    }
  if (m_data->GetKeyLocator () != 0)
    {
      Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_KeyLocator, CcnbParser::CCN_DTAG); // <KeyLocator>
      {
        Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_KeyName, CcnbParser::CCN_DTAG);    // <KeyName>
        {
          Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Name, CcnbParser::CCN_DTAG);       // <Name>
          Ccnb::SerializeName (start, *m_data->GetKeyLocator ());         //   <Component>...</Component>...
          Ccnb::AppendCloser (start);                                     // </Name>
        }
        Ccnb::AppendCloser (start);                                     // </KeyName>
      }
      Ccnb::AppendCloser (start);                                     // </KeyLocator>
    }

  Ccnb::AppendCloser (start);                                     // </SignedInfo>

  Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Content, CcnbParser::CCN_DTAG); // <Content>

  uint32_t payloadSize = m_data->GetPayload ()->GetSize ();
  if (payloadSize > 0)
    Ccnb::AppendBlockHeader (start, payloadSize, CcnbParser::CCN_BLOB);

  // there are no closing tags !!!
  // The closing tag is handled by ContentObjectTail
}

uint32_t
Data::GetSerializedSize () const
{
  size_t written = 0;
  written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_ContentObject); // <ContentObject>

  // fake signature
  written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Signature); // <Signature>
  // Signature ::= DigestAlgorithm?
  //               Witness?
  //               SignatureBits
  // if (GetSignature ().GetDigestAlgorithm () != Signature::DefaultDigestAlgorithm)
  //   {
  //     written += Ccnb::EstimateString (CcnbParser::CCN_DTAG_DigestAlgorithm, GetSignature ().GetDigestAlgorithm ());
  //   }
  written += Ccnb::EstimateTaggedBlob (CcnbParser::CCN_DTAG_SignatureBits,
                                       sizeof (m_data->GetSignature ()));      // <SignatureBits />
  written += 1;                                    // </Signature>

  written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Name);    // <Name>
  written += Ccnb::SerializedSizeName (m_data->GetName ()); //   <Component>...</Component>...
  written += 1;                                  // </Name>

  // fake signature
  written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_SignedInfo); // <SignedInfo>
  // SignedInfo ::= √PublisherPublicKeyDigest
  //                √Timestamp
  //                √Type?
  //                √FreshnessSeconds?
  //                FinalBlockID?
  //                KeyLocator?

  // written += Ccnb::EstimateTaggedBlob (CCN_DTAG_PublisherPublicKeyDigest,                          // <PublisherPublicKeyDigest>...
  //                                      sizeof (GetSignedInfo ().GetPublisherPublicKeyDigest ()));

  written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Timestamp);                  // <Timestamp>...
  written += Ccnb::EstimateTimestampBlob (m_data->GetTimestamp ());
  written += 1;

  // if (GetSignedInfo ().GetContentType () != DATA)
  //   {
  //     written += Ccnb::EstimateTaggedBlob (CcnbParser::CCN_DTAG_Type, 3);
  //   }
  if (m_data->GetFreshness () > Seconds(0))
    {
      written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_FreshnessSeconds);
      written += Ccnb::EstimateNumber (m_data->GetFreshness ().ToInteger (Time::S));
      written += 1;
    }

  if (m_data->GetKeyLocator () != 0)
    {
      written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_KeyLocator); // <KeyLocator>
      {
        written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_KeyName);    // <KeyName>
        {
          written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Name);       // <Name>
          written += Ccnb::SerializedSizeName (*m_data->GetKeyLocator ());        //   <Component>...</Component>...
          written += 1;                                               // </Name>
        }
        written += 1;                                               // </KeyName>
      }
      written += 1;                                               // </KeyLocator>
    }

  written += 1; // </SignedInfo>

  written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Content); // <Content>

  uint32_t payloadSize = m_data->GetPayload ()->GetSize ();
  if (payloadSize > 0)
    written += Ccnb::EstimateBlockHeader (payloadSize);

  // there are no closing tags !!!
  // The closing tag is handled by ContentObjectTail
  return written;
}

class ContentObjectVisitor : public CcnbParser::VoidDepthFirstVisitor
{
public:
  virtual void visit (CcnbParser::Dtag &n, boost::any param/*should be ContentObject* */)
  {
    // uint32_t n.m_dtag;
    // std::list< Ptr<CcnbParser::Block> > n.m_nestedBlocks;
    static CcnbParser::NameVisitor nameVisitor;
    static CcnbParser::NonNegativeIntegerVisitor nonNegativeIntegerVisitor;
    static CcnbParser::TimestampVisitor          timestampVisitor;
    static CcnbParser::StringVisitor      stringVisitor;
    static CcnbParser::Uint32tBlobVisitor uint32tBlobVisitor;
    static CcnbParser::ContentTypeVisitor contentTypeVisitor;

    ndn::ContentObject &contentObject = *(boost::any_cast<ndn::ContentObject*> (param));

    switch (n.m_dtag)
      {
      case CcnbParser::CCN_DTAG_ContentObject:
        // process nested blocks
        BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
          {
            block->accept (*this, param);
          }
        break;
      case CcnbParser::CCN_DTAG_Name:
        {
          // process name components
          Ptr<Name> name = Create<Name> ();
          n.accept (nameVisitor, GetPointer (name));
          contentObject.SetName (name);
          break;
        }

      case CcnbParser::CCN_DTAG_Signature:
        // process nested blocks
        BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
          {
            block->accept (*this, param);
          }
        break;

      // case CCN_DTAG_DigestAlgorithm:
      //   NS_LOG_DEBUG ("DigestAlgorithm");
      //   if (n.m_nestedTags.size ()!=1) // should be exactly one UDATA inside this tag
      //     throw CcnbParser::CcnbDecodingException ();

      //   contentObject.GetSignature ().SetDigestAlgorithm
      //     (boost::any_cast<std::string> ((*n.m_nestedTags.begin())->accept
      //                                    (stringVisitor)));
      //   break;

      case CcnbParser::CCN_DTAG_SignatureBits:
        NS_LOG_DEBUG ("SignatureBits");
        if (n.m_nestedTags.size ()!=1) // should be only one nested tag
          throw CcnbParser::CcnbDecodingException ();

        contentObject.SetSignature
          (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
                                      (uint32tBlobVisitor)));
        break;

      case CcnbParser::CCN_DTAG_SignedInfo:
        // process nested blocks
        BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
          {
            block->accept (*this, param);
          }
        break;

      // case CCN_DTAG_PublisherPublicKeyDigest:
      //   NS_LOG_DEBUG ("PublisherPublicKeyDigest");
      //   if (n.m_nestedTags.size ()!=1) // should be only one nested tag
      //     throw CcnbParser::CcnbDecodingException ();

      //   contentObject.GetSignedInfo ().SetPublisherPublicKeyDigest
      //     (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
      //                                 (uint32tBlobVisitor)));
      //   break;

      case CcnbParser::CCN_DTAG_Timestamp:
        NS_LOG_DEBUG ("Timestamp");
        if (n.m_nestedTags.size()!=1) // should be exactly one nested tag
          throw CcnbParser::CcnbDecodingException ();

        contentObject.SetTimestamp
          (boost::any_cast<Time> ((*n.m_nestedTags.begin())->accept
                                  (timestampVisitor)));
        break;

      // case CCN_DTAG_Type:
      //   NS_LOG_DEBUG ("Type");
      //   if (n.m_nestedTags.size ()!=1) // should be only one nested tag
      //     throw CcnbParser::CcnbDecodingException ();

      //   contentObject.GetSignedInfo ().SetContentType
      //     (static_cast<Data::ContentType>
      //      (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
      //                                  (contentTypeVisitor))));
      //   break;

      case CcnbParser::CCN_DTAG_FreshnessSeconds:
        NS_LOG_DEBUG ("FreshnessSeconds");

        if (n.m_nestedTags.size()!=1) // should be exactly one nested tag
          throw CcnbParser::CcnbDecodingException ();

        contentObject.SetFreshness
          (Seconds
           (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
                                       (nonNegativeIntegerVisitor))));
        break;

      case CcnbParser::CCN_DTAG_KeyLocator:
        // process nested blocks
        BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
          {
            block->accept (*this, param);
          }
        break;

      case CcnbParser::CCN_DTAG_KeyName:
        {
          if (n.m_nestedTags.size ()!=1) // should be exactly one nested tag
            throw CcnbParser::CcnbDecodingException ();

          // process name components
          Ptr<Name> name = Create<Name> ();
          n.accept (nameVisitor, GetPointer (name));
          contentObject.SetKeyLocator (name);
          break;
        }

      case CcnbParser::CCN_DTAG_Content: // !!! HACK
        // This hack was necessary for memory optimizations (i.e., content is virtual payload)
        NS_ASSERT_MSG (n.m_nestedTags.size() == 0, "Parser should have stopped just after processing <Content> tag");
        break;

      default: // ignore all other stuff
        break;
      }
  }
};

uint32_t
Data::Deserialize (Buffer::Iterator start)
{
  static ContentObjectVisitor contentObjectVisitor;

  Buffer::Iterator i = start;
  Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
  root->accept (contentObjectVisitor, GetPointer (m_data));

  return i.GetDistanceFrom (start);
}

void
Data::Print (std::ostream &os) const
{
  os << "D: " << m_data->GetName ();
  // os << "<ContentObject><Name>" << GetName () << "</Name><Content>";
}

} // ccnb
} // wire

NDN_NAMESPACE_END
