/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2013, Regents of the University of California
 *                     Yingdi Yu
 *
 * BSD license, See the LICENSE file for more information
 *
 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
 */

#include "addcontactpanel.h"
#include "ui_addcontactpanel.h"
#include <QMessageBox>

#ifndef Q_MOC_RUN
#include <ndn-cpp/security/verifier.hpp>
#include <boost/iostreams/stream.hpp>
#include "endorse-collection.pb.h"
#include "logging.h"
#endif

using namespace ndn;
using namespace ndn::ptr_lib;
using namespace std;

INIT_LOGGER("AddContactPanel");

AddContactPanel::AddContactPanel(shared_ptr<ContactManager> contactManager,
                                 QWidget *parent) 
  : QDialog(parent)
  , ui(new Ui::AddContactPanel)
  , m_contactManager(contactManager)
  , m_warningDialog(new WarningDialog())
{
  ui->setupUi(this);
  
  qRegisterMetaType<ndn::Name>("NdnName");
  qRegisterMetaType<EndorseCertificate>("EndorseCertificate");
  qRegisterMetaType<ndn::Data>("NdnData");

  connect(ui->cancelButton, SIGNAL(clicked()),
          this, SLOT(onCancelClicked()));
  connect(ui->searchButton, SIGNAL(clicked()),
          this, SLOT(onSearchClicked()));
  connect(ui->addButton, SIGNAL(clicked()),
          this, SLOT(onAddClicked()));
  connect(&*m_contactManager, SIGNAL(contactFetched(const EndorseCertificate&)),
          this, SLOT(selfEndorseCertificateFetched(const EndorseCertificate&)));
  connect(&*m_contactManager, SIGNAL(contactFetchFailed(const ndn::Name&)),
          this, SLOT(selfEndorseCertificateFetchFailed(const ndn::Name&)));
  connect(&*m_contactManager, SIGNAL(collectEndorseFetched(const ndn::Data&)),
          this, SLOT(onCollectEndorseFetched(const ndn::Data&)));
  connect(&*m_contactManager, SIGNAL(collectEndorseFetchFailed(const ndn::Name&)),
          this, SLOT(onCollectEndorseFetchFailed(const ndn::Name&)));
  connect(&*m_contactManager, SIGNAL(contactKeyFetched(const EndorseCertificate&)),
          this, SLOT(onContactKeyFetched(const EndorseCertificate&)));
  connect(&*m_contactManager, SIGNAL(contactKeyFetchFailed(const ndn::Name&)),
          this, SLOT(onContactKeyFetchFailed(const ndn::Name&)));


}

AddContactPanel::~AddContactPanel()
{
    delete ui;
    delete m_warningDialog;
}

void
AddContactPanel::onCancelClicked()
{ this->close(); }

void
AddContactPanel::onSearchClicked()
{
  m_currentEndorseCertificateReady = false;
  m_currentCollectEndorseReady = false;
  ui->infoView->clear();
  for(int i = ui->infoView->rowCount() - 1; i >= 0 ; i--)
    ui->infoView->removeRow(i);
  QString inputIdentity = ui->contactInput->text();
  m_searchIdentity = Name(inputIdentity.toStdString());

  if(Qt::Checked == ui->fetchBox->checkState())
    {
      m_contactManager->fetchSelfEndorseCertificate(m_searchIdentity);
      m_contactManager->fetchCollectEndorse(m_searchIdentity);
    }
  else
    {
      if(isCorrectName(m_searchIdentity))
        m_contactManager->fetchKey(m_searchIdentity);
      else
        {
          QMessageBox::information(this, tr("Chronos"), QString::fromStdString("Wrong key certificate name!"));
        }
    }
}

bool
AddContactPanel::isCorrectName(const Name& name)
{
  string key("KEY");
  string idCert("ID-CERT");

  if(name.get(-1).toEscapedString() != idCert)
    return false;
  
  int keyIndex = -1;
  for(int i = 0; i < name.size(); i++)
    {
      if(name.get(i).toEscapedString() == key)
        {
          keyIndex = i;
          break;
        }
    }
  
  if(keyIndex < 0)
    return false;
  else
    return true;
}

void
AddContactPanel::onAddClicked()
{
  ContactItem contactItem(*m_currentEndorseCertificate);
  try{
    m_contactManager->getContactStorage()->addContact(contactItem);
  }catch(std::exception& e){
    QMessageBox::information(this, tr("Chronos"), QString::fromStdString(e.what()));
    _LOG_ERROR("Exception: " << e.what());
    return;
  }
  emit newContactAdded();
  this->close();
}

void 
AddContactPanel::selfEndorseCertificateFetched(const EndorseCertificate& endorseCertificate)
{
  try{
    m_currentEndorseCertificate = make_shared<EndorseCertificate>(endorseCertificate);
  }catch(std::exception& e){
    QMessageBox::information(this, tr("Chronos"), QString::fromStdString(e.what()));
    _LOG_ERROR("Exception: " << e.what());
    return;
  }
  m_currentEndorseCertificateReady = true;

  if(m_currentCollectEndorseReady == true)
    displayContactInfo();
}

void
AddContactPanel::selfEndorseCertificateFetchFailed(const Name& identity)
{
  QMessageBox::information(this, tr("Chronos"), QString::fromStdString("Cannot fetch contact profile"));
}

void
AddContactPanel::onContactKeyFetched(const EndorseCertificate& endorseCertificate)
{
  try{
    m_currentEndorseCertificate = make_shared<EndorseCertificate>(endorseCertificate);
  }catch(std::exception& e){
    QMessageBox::information(this, tr("Chronos"), QString::fromStdString(e.what()));
    _LOG_ERROR("Exception: " << e.what());
    return;
  }

  m_currentCollectEndorseReady = false;

  displayContactInfo();
}

void
AddContactPanel::onContactKeyFetchFailed(const Name& identity)
{
  QMessageBox::information(this, tr("Chronos"), QString::fromStdString("Cannot fetch contact ksk certificate"));
}

void
AddContactPanel::onCollectEndorseFetched(const Data& data)
{
  m_currentCollectEndorse = make_shared<Data>(data);
  m_currentCollectEndorseReady = true;

  if(m_currentEndorseCertificateReady == true)
    displayContactInfo();
}

void
AddContactPanel::onCollectEndorseFetchFailed(const Name& identity)
{
  m_currentCollectEndorse = shared_ptr<Data>();
  m_currentCollectEndorseReady = true;
  
  if(m_currentEndorseCertificateReady == true)
    displayContactInfo();
}

void
AddContactPanel::displayContactInfo()
{
  // _LOG_TRACE("displayContactInfo");
  const Profile& profile = m_currentEndorseCertificate->getProfileData().getProfile();
  const Block& profileContent = m_currentEndorseCertificate->getProfileData().getContent();
  Buffer profileBlock(profileContent.value(), profileContent.value_size());

  map<string, int> endorseCount;

  if(static_cast<bool>(m_currentCollectEndorse))
    {
      Chronos::EndorseCollection endorseCollection;
      
      boost::iostreams::stream
        <boost::iostreams::array_source> is (reinterpret_cast<const char*>(m_currentCollectEndorse->getContent().value()), 
                                             m_currentCollectEndorse->getContent().value_size());
      
      endorseCollection.ParseFromIstream(&is);

      for(int i = 0; i < endorseCollection.endorsement_size(); i ++)
        {
          try{
            Data data;
            data.wireDecode(Block(reinterpret_cast<const uint8_t*>(endorseCollection.endorsement(i).blob().c_str()),
                                  endorseCollection.endorsement(i).blob().size()));
            EndorseCertificate endorseCert(data);
            
            Name signerKeyName = endorseCert.getSigner();
            Name signerName = signerKeyName.getPrefix(-1);
          
            shared_ptr<ContactItem> contact = m_contactManager->getContact(signerName);
            if(static_cast<bool>(contact))
              continue;

            if(!contact->isIntroducer() || !contact->canBeTrustedFor(m_currentEndorseCertificate->getProfileData().getIdentityName()))
              continue;
          
            if(!Verifier::verifySignature(data, data.getSignature(), contact->getSelfEndorseCertificate().getPublicKeyInfo()))
              continue;

            const Block& tmpProfileContent = endorseCert.getProfileData().getContent();
            Buffer tmpProfileBlock(tmpProfileContent.value(), tmpProfileContent.value_size());
            if(profileBlock != tmpProfileBlock)
              continue;

          const vector<string>& endorseList = endorseCert.getEndorseList();
          vector<string>::const_iterator it = endorseList.begin();
          for(; it != endorseList.end(); it++)
            endorseCount[*it] += 1;
          }catch(std::exception& e){
            continue;
          }
        }  
    }
  
  ui->infoView->setColumnCount(3);
  Profile::const_iterator it = profile.begin();
  int rowCount = 0;
  
  QTableWidgetItem *typeHeader = new QTableWidgetItem(QString::fromUtf8("Type"));
  ui->infoView->setHorizontalHeaderItem(0, typeHeader);
  QTableWidgetItem *valueHeader = new QTableWidgetItem(QString::fromUtf8("Value"));
  ui->infoView->setHorizontalHeaderItem(1, valueHeader);
  QTableWidgetItem *endorseHeader = new QTableWidgetItem(QString::fromUtf8("Endorse"));
  ui->infoView->setHorizontalHeaderItem(2, endorseHeader);
  
  for(; it != profile.end(); it++)
  {
    ui->infoView->insertRow(rowCount);  
    QTableWidgetItem *type = new QTableWidgetItem(QString::fromStdString(it->first));
    ui->infoView->setItem(rowCount, 0, type);
    
    QTableWidgetItem *value = new QTableWidgetItem(QString::fromStdString(it->second));
    ui->infoView->setItem(rowCount, 1, value);
    
    map<string, int>::iterator map_it = endorseCount.find(it->first);
    QTableWidgetItem *endorse = NULL;
    if(map_it == endorseCount.end())
      endorse = new QTableWidgetItem(QString::number(0));
    else
      endorse = new QTableWidgetItem(QString::number(map_it->second));
    ui->infoView->setItem(rowCount, 2, endorse);

    rowCount++;
  }
}

// bool
// AddContactPanel::isSameBlob(const ndn::Blob& blobA, const ndn::Blob& blobB)
// {
//   size_t size = blobA.size();

//   if(size != blobB.size())
//     return false;

//   const uint8_t* ap = blobA.buf();
//   const uint8_t* bp = blobB.buf();
  
//   for(int i = 0; i < size; i++)
//     {
//       if(ap[i] != bp[i])
//         return false;
//     }

//   return true;

// }


#if WAF
#include "addcontactpanel.moc"
#include "addcontactpanel.cpp.moc"
#endif
