/***************************************************************************
 * 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()
{
    delete watcher_;
}

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);
}

