/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2020, 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 "contact-panel.hpp"
#include "ui_contact-panel.h"

#include <QMenu>
#include <QItemSelectionModel>
#include <QModelIndex>
#include <QtSql/QSqlRecord>
#include <QtSql/QSqlField>
#include <QtSql/QSqlError>

namespace chronochat {

ContactPanel::ContactPanel(QWidget *parent)
  : QDialog(parent)
  , ui(new Ui::ContactPanel)
  , m_setAliasDialog(new SetAliasDialog)
  , m_contactListModel(new QStringListModel)
  , m_trustScopeModel(0)
  , m_endorseDataModel(0)
  , m_endorseComboBoxDelegate(new EndorseComboBoxDelegate)
{
  ui->setupUi(this);
  ui->ContactList->setModel(m_contactListModel);
  m_menuAlias  = new QAction("Set Alias", this);
  m_menuDelete = new QAction("Delete", this);

  connect(ui->ContactList->selectionModel(),
          SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
          this,
          SLOT(onSelectionChanged(const QItemSelection &, const QItemSelection &)));
  connect(ui->ContactList, SIGNAL(customContextMenuRequested(const QPoint&)),
          this, SLOT(onContextMenuRequested(const QPoint&)));
  connect(ui->isIntroducer, SIGNAL(stateChanged(int)),
          this, SLOT(onIsIntroducerChanged(int)));
  connect(ui->addScope, SIGNAL(clicked()),
          this, SLOT(onAddScopeClicked()));
  connect(ui->deleteScope, SIGNAL(clicked()),
          this, SLOT(onDeleteScopeClicked()));
  connect(ui->saveButton, SIGNAL(clicked()),
          this, SLOT(onSaveScopeClicked()));
  connect(ui->endorseButton, SIGNAL(clicked()),
          this, SLOT(onEndorseButtonClicked()));
  connect(m_setAliasDialog, SIGNAL(aliasChanged(const QString&, const QString&)),
          this, SLOT(onAliasChanged(const QString&, const QString&)));
}

ContactPanel::~ContactPanel()
{
  if (m_contactListModel)
    delete m_contactListModel;
  if (m_trustScopeModel)
    delete m_trustScopeModel;
  if (m_endorseDataModel)
    delete m_endorseDataModel;

  delete m_setAliasDialog;
  delete m_endorseComboBoxDelegate;

  delete m_menuAlias;
  delete m_menuDelete;

  delete ui;
}

//private methods
void
ContactPanel::resetPanel()
{
  // Clean up General tag.
  ui->NameData->clear();
  ui->NameSpaceData->clear();
  ui->InstitutionData->clear();

  // Clean up TrustScope tag.
  ui->isIntroducer->setChecked(false);
  ui->addScope->setEnabled(false);
  ui->deleteScope->setEnabled(false);

  m_trustScopeModel = new QSqlTableModel;
  m_trustScopeModel->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
  m_trustScopeModel->setHeaderData(1, Qt::Horizontal, QObject::tr("Contact"));
  m_trustScopeModel->setHeaderData(2, Qt::Horizontal, QObject::tr("TrustScope"));

  ui->trustScopeList->setModel(m_trustScopeModel);
  ui->trustScopeList->setColumnHidden(0, true);
  ui->trustScopeList->setColumnHidden(1, true);
  ui->trustScopeList->show();
  ui->trustScopeList->setEnabled(false);

  // Clean up Endorse tag.
  m_endorseDataModel = new QSqlTableModel;
  m_endorseDataModel->setHeaderData(0, Qt::Horizontal, QObject::tr("Identity"));
  m_endorseDataModel->setHeaderData(1, Qt::Horizontal, QObject::tr("Type"));
  m_endorseDataModel->setHeaderData(2, Qt::Horizontal, QObject::tr("Value"));
  m_endorseDataModel->setHeaderData(3, Qt::Horizontal, QObject::tr("Endorse"));

  ui->endorseList->setModel(m_endorseDataModel);
  ui->endorseList->setColumnHidden(0, true);
  ui->endorseList->resizeColumnToContents(1);
  ui->endorseList->resizeColumnToContents(2);
  ui->endorseList->setItemDelegateForColumn(3, m_endorseComboBoxDelegate);
  ui->endorseList->show();
  ui->endorseList->setEnabled(false);

  // Clean up contact list.
  m_contactAliasList.clear();
  m_contactIdList.clear();
  m_currentSelectedContact.clear();
  m_contactListModel->setStringList(m_contactAliasList);
}

// public slots
void
ContactPanel::onCloseDBModule()
{
  if (m_trustScopeModel)
    delete m_trustScopeModel;
  if (m_endorseDataModel)
    delete m_endorseDataModel;
}

void
ContactPanel::onIdentityUpdated(const QString& identity)
{
  resetPanel();

  emit waitForContactList();  // Re-load contact list;
}

void
ContactPanel::onContactAliasListReady(const QStringList& aliasList)
{
  m_contactAliasList = aliasList;
  m_contactListModel->setStringList(m_contactAliasList);
}

void
ContactPanel::onContactIdListReady(const QStringList& idList)
{
  m_currentSelectedContact.clear();
  m_contactIdList = idList;
}

void
ContactPanel::onContactInfoReady(const QString& identity,
                                 const QString& name,
                                 const QString& institute,
                                 bool isIntro)
{
  ui->NameData->setText(name);
  ui->NameSpaceData->setText(identity);
  ui->InstitutionData->setText(institute);

  QString filter = QString("contact_namespace = '%1'").arg(identity);
  m_trustScopeModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
  m_trustScopeModel->setTable("TrustScope");
  m_trustScopeModel->setFilter(filter);
  m_trustScopeModel->select();
  ui->trustScopeList->setModel(m_trustScopeModel);
  ui->trustScopeList->setColumnHidden(0, true);
  ui->trustScopeList->setColumnHidden(1, true);
  ui->trustScopeList->show();

  if (isIntro) {
    ui->isIntroducer->setChecked(true);
    ui->addScope->setEnabled(true);
    ui->deleteScope->setEnabled(true);
    ui->trustScopeList->setEnabled(true);
  }
  else {
    ui->isIntroducer->setChecked(false);
    ui->addScope->setEnabled(false);
    ui->deleteScope->setEnabled(false);
    ui->trustScopeList->setEnabled(false);
  }

  QString filter2 = QString("profile_identity = '%1'").arg(identity);
  m_endorseDataModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
  m_endorseDataModel->setTable("ContactProfile");
  m_endorseDataModel->setFilter(filter2);
  m_endorseDataModel->select();
  ui->endorseList->setModel(m_endorseDataModel);
  ui->endorseList->setColumnHidden(0, true);
  ui->endorseList->resizeColumnToContents(1);
  ui->endorseList->resizeColumnToContents(2);
  ui->endorseList->setItemDelegateForColumn(3, m_endorseComboBoxDelegate);
  ui->endorseList->show();
  ui->endorseList->setEnabled(true);
}

// private slots
void
ContactPanel::onSelectionChanged(const QItemSelection& selected,
                                 const QItemSelection& deselected)
{
  QModelIndexList items = selected.indexes();
  QString alias = m_contactListModel->data(items.first(), Qt::DisplayRole).toString();

  bool contactFound = false;
  for (int i = 0; i < m_contactAliasList.size(); i++) {
    if (alias == m_contactAliasList[i]) {
      contactFound = true;
      m_currentSelectedContact = m_contactIdList[i];
      break;
    }
  }

  if (!contactFound) {
    emit warning("This should not happen: ContactPanel::updateSelection #1");
    return;
  }

  emit waitForContactInfo(m_currentSelectedContact);
}

void
ContactPanel::onContextMenuRequested(const QPoint& pos)
{
  QMenu menu(ui->ContactList);

  menu.addAction(m_menuAlias);
  connect(m_menuAlias, SIGNAL(triggered()),
          this, SLOT(onSetAliasDialogRequested()));

  menu.addAction(m_menuDelete);
  connect(m_menuDelete, SIGNAL(triggered()),
          this, SLOT(onContactDeletionRequested()));

  menu.exec(ui->ContactList->mapToGlobal(pos));
}

void
ContactPanel::onSetAliasDialogRequested()
{
  for (int i = 0; i < m_contactIdList.size(); i++)
    if (m_contactIdList[i] == m_currentSelectedContact) {
      m_setAliasDialog->setTargetIdentity(m_currentSelectedContact, m_contactAliasList[i]);
      m_setAliasDialog->show();
      return;
    }
}

void
ContactPanel::onContactDeletionRequested()
{
  QItemSelectionModel* selectionModel = ui->ContactList->selectionModel();
  QModelIndexList selectedList = selectionModel->selectedIndexes();

  for (QModelIndexList::iterator it = selectedList.begin(); it != selectedList.end(); it++) {
    QString alias =  m_contactListModel->data(*it, Qt::DisplayRole).toString();
    for (int i = 0; i < m_contactAliasList.size(); i++)
      if (m_contactAliasList[i] == alias) {
        emit removeContact(m_contactIdList[i]);
        return;
      }
  }
}

void
ContactPanel::onIsIntroducerChanged(int state)
{
  if (state == Qt::Checked) {
    ui->addScope->setEnabled(true);
    ui->deleteScope->setEnabled(true);
    ui->trustScopeList->setEnabled(true);
    emit updateIsIntroducer(m_currentSelectedContact, true);
  }
  else {
    ui->addScope->setEnabled(false);
    ui->deleteScope->setEnabled(false);
    ui->trustScopeList->setEnabled(false);
    emit updateIsIntroducer(m_currentSelectedContact, false);
  }
}

void
ContactPanel::onAddScopeClicked()
{
  int rowCount = m_trustScopeModel->rowCount();
  QSqlRecord record;
  QSqlField identityField("contact_namespace", QVariant::String);
  record.append(identityField);
  record.setValue("contact_namespace", m_currentSelectedContact);
  m_trustScopeModel->insertRow(rowCount);
  m_trustScopeModel->setRecord(rowCount, record);
}

void
ContactPanel::onDeleteScopeClicked()
{
  QItemSelectionModel* selectionModel = ui->trustScopeList->selectionModel();
  QModelIndexList indexList = selectionModel->selectedIndexes();

  for (int i = indexList.size() - 1; i >= 0; i--)
    m_trustScopeModel->removeRow(indexList[i].row());

  m_trustScopeModel->submitAll();
}

void
ContactPanel::onSaveScopeClicked()
{
  m_trustScopeModel->submitAll();
}

void
ContactPanel::onEndorseButtonClicked()
{
  m_endorseDataModel->submitAll();
  emit updateEndorseCertificate(m_currentSelectedContact);
}

void
ContactPanel::onAliasChanged(const QString& identity, const QString& alias)
{
  emit updateAlias(identity, alias);
}

} // namespace chronochat

#if WAF
#include "contact-panel.moc"
#endif
