/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2012 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: Zhenkai Zhu <zhenkai@cs.ucla.edu>
 *         Chaoyi Bian <bcy@pku.edu.cn>
 *	   Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#include "sync-state.h"
#include "sync-diff-leaf.h"
#include "sync-std-name-info.h"

#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/throw_exception.hpp>
#include <boost/lexical_cast.hpp>

using namespace std;
using namespace boost;

typedef error_info<struct tag_errmsg, string> info_str; 

using namespace Sync::Error;

namespace Sync {

/*
std::ostream &
operator << (std::ostream &os, const State &state)
{
  os << "<state>"; DEBUG_ENDL;
  
  BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
    {
      shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
      if (diffLeaf != 0)
        {
          os << "<item action=\"" << diffLeaf->getOperation () << "\">"; DEBUG_ENDL;
        }
      else
        {
          os << "<item>"; DEBUG_ENDL;
        }
      os << "<name>" << *leaf->getInfo () << "</name>"; DEBUG_ENDL;
      if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
        {
          os << "<seq>" << leaf->getSeq () << "</seq>"; DEBUG_ENDL;
        }
      os << "</item>"; DEBUG_ENDL;
    }
  os << "</state>";
}
*/

SyncStateMsg &
operator << (SyncStateMsg &ossm, const State &state)
{
  BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
  {
    SyncState *oss = ossm.add_ss();
    shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
    if (diffLeaf != 0 && diffLeaf->getOperation() != UPDATE)
    {
      oss->set_type(SyncState::DELETE);
    }
    else
    {
      oss->set_type(SyncState::UPDATE);
    }

    std::ostringstream os;
    os << *leaf->getInfo();
    oss->set_name(os.str());

    if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
    {
      SyncState::SeqNo *seqNo = oss->mutable_seqno();
      seqNo->set_session(leaf->getSeq().getSession());
      seqNo->set_seq(leaf->getSeq().getSeq());
    }
  }
  return ossm;
}

/*
std::istream &
operator >> (std::istream &in, State &state)
{
  TiXmlDocument doc;
  in >> doc;

  if (doc.RootElement() == 0)
        BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("Empty XML"));
  
  for (TiXmlElement *iterator = doc.RootElement()->FirstChildElement ("item");
       iterator != 0;
       iterator = iterator->NextSiblingElement("item"))
    {
      TiXmlElement *name = iterator->FirstChildElement ("name");
      if (name == 0 || name->GetText() == 0)
        BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<name> element is missing"));
        
      NameInfoConstPtr info = StdNameInfo::FindOrCreate (name->GetText());
      
      if (iterator->Attribute("action") == 0 || strcmp(iterator->Attribute("action"), "update") == 0)
        {
          TiXmlElement *seq = iterator->FirstChildElement ("seq");
          if (seq == 0)
            BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seq> element is missing"));
          
          TiXmlElement *session = seq->FirstChildElement ("session");
          TiXmlElement *seqno = seq->FirstChildElement ("seqno");

          if (session == 0 || session->GetText() == 0)
            BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<session> element is missing"));
          if (seqno == 0 || seqno->GetText() == 0)
            BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seqno> element is missing"));

          state.update (info, SeqNo (
                                     lexical_cast<uint32_t> (session->GetText()),
                                     lexical_cast<uint32_t> (seqno->GetText())
                                     ));
        }
      else
        {
          state.remove (info);
        }
    }

  return in;
}
*/

SyncStateMsg &
operator >> (SyncStateMsg &issm, State &state)
{
  int n = issm.ss_size();
  for (int i = 0; i < n; i++)
  {
    const SyncState &ss = issm.ss(i);
    NameInfoConstPtr info = StdNameInfo::FindOrCreate (ss.name());
    if (ss.type() == SyncState::UPDATE)
    {
      uint32_t session = lexical_cast<uint32_t>(ss.seqno().session());
      uint32_t seq = lexical_cast<uint32_t>(ss.seqno().seq());
      SeqNo seqNo(session, seq);
      state.update(info, seqNo);
    }
    else
    {
      state.remove(info);
    }
  }
  return issm;
}

}
