/* -*- 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::AppendName (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::AppendName (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>

  // 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::EstimateName (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::EstimateName (*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>

  // 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> ();

          BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
            {
              block->accept (nameVisitor, &(*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 ();

          Ptr<CcnbParser::BaseTag> nameTag = DynamicCast<CcnbParser::BaseTag>(n.m_nestedTags.front ());
          if (nameTag == 0)
            throw CcnbParser::CcnbDecodingException ();

          // process name components
          Ptr<Name> name = Create<Name> ();

          BOOST_FOREACH (Ptr<CcnbParser::Block> block, nameTag->m_nestedTags)
            {
              block->accept (nameVisitor, &(*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
