/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2017, Regents of the University of California.
 *
 * This file is part of ChronoShare, a decentralized file sharing application over NDN.
 *
 * ChronoShare is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * ChronoShare 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 copies of the GNU General Public License along with
 * ChronoShare, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ChronoShare authors and contributors.
 */

#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>

#include "action-log.hpp"
#include "logging.hpp"

#include <boost/filesystem.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
#include <unistd.h>

using namespace std;
using namespace boost;
using namespace Ndnx;
namespace fs = boost::filesystem;

BOOST_AUTO_TEST_SUITE(TestActionLog)

BOOST_AUTO_TEST_CASE(ActionLogTest)
{
  Name localName("/alex");

  fs::path tmpdir = fs::unique_path(fs::temp_directory_path() / "%%%%-%%%%-%%%%-%%%%");
  SyncLogPtr syncLog = make_shared<SyncLog>(tmpdir, localName);
  CcnxWrapperPtr ccnx = make_shared<CcnxWrapper>();

  ActionLogPtr actionLog =
    make_shared<ActionLog>(ccnx, tmpdir, syncLog, "top-secret", "test-chronoshare",
                           ActionLog::OnFileAddedOrChangedCallback(),
                           ActionLog::OnFileRemovedCallback());

  // const std::string &filename,
  //                    const Hash &hash,
  //                    time_t wtime,
  //                    int mode,
  //                    int seg_num
  BOOST_CHECK_EQUAL(syncLog->SeqNo(localName), 0);

  BOOST_CHECK_EQUAL(syncLog->LogSize(), 0);
  BOOST_CHECK_EQUAL(actionLog->LogSize(), 0);

  actionLog->AddLocalActionUpdate("file.txt",
                                  *Hash::FromString(
                                    "2ff304769cdb0125ac039e6fe7575f8576dceffc62618a431715aaf6eea2bf1c"),
                                  time(NULL), 0755, 10);

  BOOST_CHECK_EQUAL(syncLog->SeqNo(localName), 1);
  BOOST_CHECK_EQUAL(syncLog->LogSize(), 0);
  BOOST_CHECK_EQUAL(actionLog->LogSize(), 1);

  HashPtr hash = syncLog->RememberStateInStateLog();
  BOOST_CHECK_EQUAL(syncLog->LogSize(), 1);
  BOOST_CHECK_EQUAL(lexical_cast<string>(*hash),
                    "3410477233f98d6c3f9a6f8da24494bf5a65e1a7c9f4f66b228128bd4e020558");

  PcoPtr pco = actionLog->LookupActionPco(localName, 0);
  BOOST_CHECK_EQUAL((bool)pco, false);

  pco = actionLog->LookupActionPco(localName, 1);
  BOOST_CHECK_EQUAL((bool)pco, true);

  BOOST_CHECK_EQUAL(pco->name(), "/alex/test-chronoshare/action/top-secret/%00%01");

  ActionItemPtr action = actionLog->LookupAction(Name("/alex/test-chronoshare/action/top-secret")(0));
  BOOST_CHECK_EQUAL((bool)action, false);

  action = actionLog->LookupAction(Name("/alex/test-chronoshare/action/top-secret")(1));
  BOOST_CHECK_EQUAL((bool)action, true);

  if (action) {
    BOOST_CHECK_EQUAL(action->version(), 0);
    BOOST_CHECK_EQUAL(action->action(), 0);

    BOOST_CHECK_EQUAL(action->filename(), "file.txt");
    BOOST_CHECK_EQUAL(action->seg_num(), 10);
    BOOST_CHECK_EQUAL(action->file_hash().size(), 32);
    BOOST_CHECK_EQUAL(action->mode(), 0755);

    BOOST_CHECK_EQUAL(action->has_parent_device_name(), false);
    BOOST_CHECK_EQUAL(action->has_parent_seq_no(), false);
  }

  actionLog->AddLocalActionUpdate("file.txt",
                                  *Hash::FromString(
                                    "2ff304769cdb0125ac039e6fe7575f8576dceffc62618a431715aaf6eea2bf1c"),
                                  time(NULL), 0755, 10);
  BOOST_CHECK_EQUAL(syncLog->SeqNo(localName), 2);
  BOOST_CHECK_EQUAL(syncLog->LogSize(), 1);
  BOOST_CHECK_EQUAL(actionLog->LogSize(), 2);

  action = actionLog->LookupAction(Name("/alex"), 2);
  BOOST_CHECK_EQUAL((bool)action, true);

  if (action) {
    BOOST_CHECK_EQUAL(action->has_parent_device_name(), true);
    BOOST_CHECK_EQUAL(action->has_parent_seq_no(), true);

    BOOST_CHECK_EQUAL(action->parent_seq_no(), 1);
    BOOST_CHECK_EQUAL(action->version(), 1);
  }

  BOOST_CHECK_EQUAL((bool)actionLog->AddRemoteAction(pco), true);
  BOOST_CHECK_EQUAL(actionLog->LogSize(), 2);

  // create a real remote action
  ActionItem item;
  item.set_action(ActionItem::UPDATE);
  item.set_filename("file.txt");
  item.set_version(2);
  item.set_timestamp(time(NULL));

  BytesPtr item_msg = serializeMsg(item);
  Name actionName = Name("/")(Name("/zhenkai/test"))("test-chronoshare")("action")("top-secret")(1);
  Bytes actionData = ccnx->createContentObject(actionName, head(*item_msg), item_msg->size());

  pco = make_shared<ParsedContentObject>(actionData);
  BOOST_CHECK_EQUAL((bool)actionLog->AddRemoteAction(pco), true);
  BOOST_CHECK_EQUAL(actionLog->LogSize(), 3);

  remove_all(tmpdir);
}

BOOST_AUTO_TEST_SUITE_END()

// catch (boost::exception &err)
//   {
//     cout << *boost::get_error_info<errmsg_info_str> (err) << endl;
//   }
