/* -*- 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(SignatureSha256WithRsa::Error &e){
    return false;
  }catch(KeyLocator::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(SignatureSha256WithRsa::Error &e){
    return false;
  }catch(KeyLocator::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
