/***************************************************************************
 * Copyright (C) 2015-2016 by Savoir-faire Linux                                *
 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
 *                                                                         *
 * This program 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.                                     *
 *                                                                         *
 * This program 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 a copy of the GNU General Public License       *
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
 **************************************************************************/

#include "windowscontactbackend.h"

#include <QtXml>
#include <QPainter>

#include "personmodel.h"
#include "categorizedcontactmodel.h"

#include "utils.h"

WindowsContactEditor::WindowsContactEditor(CollectionMediator<Person> *m
                                           , WindowsContactBackend *parent)
    : CollectionEditor<Person>(m),collection_(parent)
{

}

WindowsContactEditor::~WindowsContactEditor()
{

}

bool
WindowsContactEditor::save(const Person *item)
{
    QFile file(QStandardPaths::writableLocation
               (QStandardPaths::HomeLocation) + "/Contacts/"
               + item->formattedName() + ".contact");
    if (!file.open(QIODevice::ReadWrite)) {
        file.close();
        qDebug() << "Cannot open contact file";
        return false;
    }

    QDomDocument doc;
    doc.setContent(&file);

    auto root = doc.elementsByTagName("c:contact").at(0);
    auto nodes = doc.elementsByTagName("c:PhoneNumberCollection");

    //if PhoneNumberCollection already exists
    QVector<QString> nodeNumberVector;
    if (nodes.length()) {
        auto phoneNumberCollection = nodes.at(0);
        auto phoneNumbers = doc.elementsByTagName("c:Number");
        auto virtualPhoneNumber = item->phoneNumbers();
        for (int i = 0; i < phoneNumbers.length(); i++) {
            auto node = phoneNumbers.at(i).toElement();
            nodeNumberVector.append(node.text());
        }
        for (auto elem : virtualPhoneNumber) {
            if (not nodeNumberVector.contains(elem->uri())) {
                auto phoneNumber = doc.createElement("c:PhoneNumber");
                phoneNumberCollection.appendChild(phoneNumber);
                phoneNumber.setAttribute("c:ElementID", Utils::GenGUID());
                auto numberNode = doc.createElement("c:Number");
                phoneNumber.appendChild(numberNode);
                auto numberValue = doc.createTextNode(elem->uri());
                numberNode.appendChild(numberValue);
            }
        }
    } else {
        auto phoneNumberCollection = doc.createElement("c:PhoneNumberCollection");
        root.appendChild(phoneNumberCollection);
        auto phoneNumber = doc.createElement("c:PhoneNumber");
        phoneNumberCollection.appendChild(phoneNumber);
        phoneNumber.setAttribute("c:ElementID", Utils::GenGUID());
        auto numberNode = doc.createElement("c:Number");
        phoneNumber.appendChild(numberNode);
        auto numberValue = doc.createTextNode(item->phoneNumbers().at(0)->uri());
        numberNode.appendChild(numberValue);
    }
    file.resize(0);
    file.write(doc.toByteArray());
    file.close();
    return true;
}

bool
WindowsContactEditor::remove(const Person *item)
{
    items_.removeOne(const_cast<Person*>(item));
    mediator()->removeItem(item);
    return true;
}

bool
WindowsContactEditor::edit(Person *item)
{
    Q_UNUSED(item)
    return false;
}

bool
WindowsContactEditor::addNew(Person *item)
{
    QDomDocument doc;
    QFile file(QStandardPaths::writableLocation
               (QStandardPaths::HomeLocation) + "/Contacts/"
               + item->formattedName()+".contact");
    if (file.exists())
        return false;
    if (!file.open(QIODevice::ReadWrite)) {
        file.close();
        qDebug() << "Cannot create contact file";
        return false;
    }
    doc.appendChild(
                doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\""));

    //Create root
    auto root = doc.createElement("c:contact");
    root.setAttribute("c:Version", "1");
    root.setAttribute("xmlns:c", "http://schemas.microsoft.com/Contact");
    root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
    root.setAttribute("xmlns:MSP2P","http://schemas.microsoft.com/Contact/Extended/MSP2P");
    doc.appendChild(root);

    auto date = Utils::GetISODate();

    //Create creation date
    auto creationDateNode = doc.createElement("c:CreationDate");
    auto creationDateValue = doc.createTextNode(date);
    creationDateNode.appendChild(creationDateValue);
    root.appendChild(creationDateNode);

    //Create extended node
    auto extendedNode = doc.createElement("c:Extended");
    extendedNode.setAttribute("xsi:nil", "true");
    root.appendChild(extendedNode);

    //Create contactID collection
    auto contactIDCol = doc.createElement("c:ContactIDCollection");
    root.appendChild(contactIDCol);
    auto contactID = doc.createElement("c:ContactID");
    contactID.setAttribute("c:ElementID", Utils::GenGUID());
    auto contactValue = doc.createElement("c:Value");
    auto value = doc.createTextNode(item->uid());
    contactValue.appendChild(value);
    contactID.appendChild(contactValue);
    contactIDCol.appendChild(contactID);

    //Create NameCollection
    auto nameCollection = doc.createElement("c:NameCollection");
    root.appendChild(nameCollection);
    auto name = doc.createElement("c:Name");
    nameCollection.appendChild(name);
    name.setAttribute("c:ElementID", Utils::GenGUID());
    auto formattedName = doc.createElement("c:FormattedName");
    name.appendChild(formattedName);
    auto formattedNameValue = doc.createTextNode(item->formattedName());
    formattedName.appendChild(formattedNameValue);

    //Create PhoneNumberCollection
    auto phoneNumberCollection = doc.createElement("c:PhoneNumberCollection");
    root.appendChild(phoneNumberCollection);
    auto phoneNumber = doc.createElement("c:PhoneNumber");
    phoneNumberCollection.appendChild(phoneNumber);
    phoneNumber.setAttribute("c:ElementID", Utils::GenGUID());
    auto numberNode = doc.createElement("c:Number");
    phoneNumber.appendChild(numberNode);
    auto numberValue = doc.createTextNode(item->phoneNumbers().at(0)->uri());
    numberNode.appendChild(numberValue);

    //Write to file
    file.write(doc.toByteArray());
    file.close();

    return true;
}

bool
WindowsContactEditor::addExisting(const Person *item)
{
    items_ << const_cast<Person*>(item);
    mediator()->addItem(item);
    return true;
}

QVector<Person*>
WindowsContactEditor::items() const
{
    return items_;
}

WindowsContactBackend::WindowsContactBackend(CollectionMediator<Person>* mediator,
                                             CollectionInterface* parent)
    : CollectionInterface(new WindowsContactEditor(mediator,this), parent)
    , mediator_(mediator), watcher_(new QFileSystemWatcher())
{

}

WindowsContactBackend::~WindowsContactBackend()
{

}

bool
WindowsContactBackend::load()
{
    QtConcurrent::run(this, &WindowsContactBackend::loadRun);
    watcher_->addPath(QStandardPaths::writableLocation
                      (QStandardPaths::HomeLocation) + "/Contacts");

    QObject::connect(watcher_, &QFileSystemWatcher::directoryChanged, [=](QString path) {
        Q_UNUSED(path)
        QtConcurrent::run(this, &WindowsContactBackend::loadRun);
    });
    return true;
}

bool
WindowsContactBackend::loadRun()
{
    QDir contactDir(QStandardPaths::writableLocation
                    (QStandardPaths::HomeLocation) + "/Contacts");
    QStringList filesList = contactDir.entryList(QStringList("*.contact"));
    auto ret = true;
    for(auto contactFileName : filesList) {
        if (not getPersonFromContactFile(contactDir, contactFileName))
            ret = false;
    }
    return ret;
}

bool
WindowsContactBackend::getPersonFromContactFile(const QDir& contactDir,
                                                const QString &contactFileName)
{
    QString contactFilePath
            (contactDir.absolutePath() + "/" +  contactFileName);
    QFile contactFile(contactFilePath);
    if (contactFile.open(QIODevice::ReadOnly)) {
        QXmlStreamReader reader;
        Person *p = new Person(this);
        QVector<ContactMethod*> contactMethod;
        reader.setDevice(&contactFile);
        while (!reader.atEnd()) {
            reader.readNext();
            if (reader.isStartElement()) {
                QString name = reader.name().toString();
                if (name == "FormattedName")
                    p->setFormattedName(reader.readElementText());
                else if (name == "NickName")
                    p->setNickName(reader.readElementText());
                else if (name == "GivenName")
                    p->setFirstName(reader.readElementText());
                else if (name == "FamilyName")
                    p->setFamilyName(reader.readElementText());
                else if (name == "Company")
                    p->setOrganization(reader.readElementText());
                else if (name == "Department")
                    p->setDepartment(reader.readElementText());
                else if (name == "Number") {
                    QString number = reader.readElementText();
                    if (not number.isEmpty()) {
                        ContactMethod *contact =
                                PhoneDirectoryModel::instance().getNumber(number,p);
                        contactMethod.append(contact);
                    }
                } else if (name == "ContactID") {
                    while (reader.name().toString() != "Value")
                        reader.readNext();
                    p->setUid(reader.readElementText().toUtf8());
                }
                else if (name == "Photo") {
                    //FIXME: It seems to be possible to have multiple photo...
                    reader.readNext();
                    if (reader.name().toString() == "Url") {
                        QString photoValue = reader.readElementText();
                        QImage photo;
                        photo.load(photoValue);
                        if (not photo.isNull())
                            p->setPhoto(getCirclePhoto(photo));
                    }
                }
                else if (name == "EmailAddress") {
                    QString address;
                    bool isPreferred = false;
                    reader.readNext();
                    while (reader.name().toString() != "EmailAddress"
                           && !reader.atEnd()) {
                        if (reader.isStartElement()) {
                            QString tag = reader.name().toString();
                            if (tag == "Address")
                                address = reader.readElementText();
                            else if (tag == "Label")
                                if (reader.readElementText() == "Preferred")
                                    isPreferred = true;
                        }
                        reader.readNext();
                    }
                    if (isPreferred)
                        p->setPreferredEmail(address);
                }
            }
        }
        if (reader.hasError()) {
            qDebug() << reader.errorString();
            contactFile.close();
            return false;
        } else {
            Person* existing = PersonModel::instance().getPersonByUid(p->uid());
            if (existing) {
                if (contactMethod.size() > 0)
                    existing->setContactMethods ( contactMethod   );
                existing->setNickName       ( p->nickName()       );
                existing->setFirstName      ( p->firstName()      );
                existing->setFamilyName     ( p->secondName()     );
                existing->setFormattedName  ( p->formattedName()  );
                existing->setOrganization   ( p->organization()   );
                existing->setPreferredEmail ( p->preferredEmail() );
                existing->setGroup          ( p->group()          );
                existing->setDepartment     ( p->department()     );
                existing->setPhoto          ( p->photo()          );
                delete p;
            } else {
                p->setContactMethods(contactMethod);
                editor<Person>()->addExisting(p);
            }
            return true;
        }
    } else {
        qDebug() << "Error Opening contact file : " << contactFileName;
        return false;
    }
}

QImage WindowsContactBackend::getCirclePhoto(const QImage original)
{
    QImage target(sizePhoto_, sizePhoto_, QImage::Format_ARGB32_Premultiplied);
    target.fill(Qt::transparent);

    QPainter painter(&target);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    painter.setBrush(QBrush(Qt::white));
    painter.drawEllipse(0, 0, sizePhoto_, sizePhoto_);
    painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
    painter.drawImage(0, 0,
                      original
                      .scaled(60, 60, Qt::KeepAspectRatio, Qt::SmoothTransformation)
                      .convertToFormat(QImage::Format_ARGB32_Premultiplied));
    return target;
}

bool
WindowsContactBackend::reload()
{
    return false;
}

bool
WindowsContactBackend::clear()
{
    return false;
}

QString
WindowsContactBackend::name() const
{
    return "Windows Contact Backend";
}

QString
WindowsContactBackend::category() const
{
    return "Contacts";
}

bool
WindowsContactBackend::isEnabled() const
{
    return true;
}

QByteArray
WindowsContactBackend::id() const
{
    return "wincb";
}

FlagPack<CollectionInterface::SupportedFeatures> WindowsContactBackend::supportedFeatures() const
{
    return (
                CollectionInterface::SupportedFeatures::NONE |
                CollectionInterface::SupportedFeatures::LOAD |
                CollectionInterface::SupportedFeatures::SAVE |
                CollectionInterface::SupportedFeatures::REMOVE |
                CollectionInterface::SupportedFeatures::ADD);
}

