/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#include "common.hpp"

#include "sec-rule-relative.hpp"

#include "signature-sha256-with-rsa.hpp"
#include "security-common.hpp"

#include "../util/logging.hpp"

INIT_LOGGER ("ndn.SecRuleRelative");

using namespace std;

namespace ndn {

SecRuleRelative::SecRuleRelative (const string& dataRegex, const string& signerRegex,
                                  const string& op,
                                  const string& dataExpand, const string& signerExpand,
                                  bool isPositive)
  : SecRule(isPositive),
    m_dataRegex(dataRegex),
    m_signerRegex(signerRegex),
    m_op(op),
    m_dataExpand(dataExpand),
    m_signerExpand(signerExpand),
    m_dataNameRegex(dataRegex, dataExpand),
    m_signerNameRegex(signerRegex, signerExpand)
{
  if (op != ">" && op != ">=" && op != "==")
    throw Error("op is wrong!");
}

SecRuleRelative::~SecRuleRelative()
{
}

bool
SecRuleRelative::satisfy (const Data& data)
{
  Name dataName = data.getName();
  try
    {
      SignatureSha256WithRsa sig(data.getSignature());
      Name signerName = sig.getKeyLocator().getName ();
      return satisfy (dataName, signerName);
    }
  catch (std::runtime_error& e)
    {
      return false;
    }
}

bool
SecRuleRelative::satisfy (const Name& dataName, const Name& signerName)
{
  if (!m_dataNameRegex.match(dataName))
    return false;
  Name expandDataName = m_dataNameRegex.expand();

  if (!m_signerNameRegex.match(signerName))
    return false;
  Name expandSignerName =  m_signerNameRegex.expand();

  bool matched = compare(expandDataName, expandSignerName);

  return matched;
}

bool
SecRuleRelative::matchDataName (const Data& data)
{
  return m_dataNameRegex.match(data.getName());
}

bool
SecRuleRelative::matchSignerName (const Data& data)
{
  try
    {
      SignatureSha256WithRsa sig(data.getSignature());
      Name signerName = sig.getKeyLocator().getName ();
      return m_signerNameRegex.match(signerName);
    }
  catch (std::runtime_error& e)
    {
      return false;
    }
}

bool
SecRuleRelative::compare(const Name& dataName, const Name& signerName)
{
  if ((dataName == signerName) && ("==" == m_op || ">=" == m_op))
    return true;

  Name::const_iterator i = dataName.begin ();
  Name::const_iterator j = signerName.begin ();

  for (; i != dataName.end () && j != signerName.end (); i++, j++)
    {
      if ((i->compare(*j)) == 0)
        continue;
      else
        return false;
    }

  if (i == dataName.end())
    return false;
  else
    return true;
}

} // namespace ndn
