//  This file is part of Friendiqa
//  https://git.friendi.ca/lubuwest/Friendiqa
//  Copyright (C) 2020 Marco R. <thomasschmidt45@gmx.net>
//
//  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.
//
//  In addition, as a special exception, the copyright holders give
//  permission to link the code of portions of this program with the
//  OpenSSL library under certain conditions as described in each
//  individual source file, and distribute linked combinations including
//  the two.
//
//  You must obey the GNU General Public License in all respects for all
//  of the code used other than OpenSSL. If you modify file(s) with this
//  exception, you may extend this exception to your version of the
//  file(s), but you are not obligated to do so. If you do not wish to do
//  so, delete this exception statement from your version. If you delete
//  this exception statement from all source files in the program, then
//  also delete it here.
//
//  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 "updatenews.h"

#include <QHttpPart>
#include <QTextCodec>
#include <QUrlQuery>
#include <QList>
#include <QDataStream>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QQmlEngine>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlDatabase>
#include <QSqlError>
#include <QDateTime>
//#include "AndroidNative/systemdispatcher.h"



UPDATENEWS *UPDATENEWS::instance()
{
    static UPDATENEWS udn;
    return &udn;
}

UPDATENEWS::UPDATENEWS(QObject *parent) : QObject(parent)
{

}

void UPDATENEWS::setUrl(QString url)
{
   if (url!=m_url) {
       m_url = url;
       xhr.setUrl(url);
       emit urlChanged(m_url);
   }
}


void UPDATENEWS::setDatabase()
{
    static QQmlEngine qe;
    QString db_url=qe.offlineStorageDatabaseFilePath("Friendiqa");
    m_db = QSqlDatabase::addDatabase("QSQLITE");
    m_db.setDatabaseName(QUrl("file://"+db_url+".sqlite").toLocalFile());
    //qDebug() << db_url;

      if (!m_db.open())
      {
         qDebug() << "Error: connection with database fail " << m_db.lastError();
      }
}


void UPDATENEWS::login()
{
    QSqlQuery query("SELECT * FROM config WHERE isActive=0",m_db);
    while (query.next())
    {
       username = query.value(1).toString();
       QByteArray bpassword=query.value(2).toByteArray();
       QString password=QByteArray::fromBase64(bpassword);
       m_login=username+":"+password ;
       xhr.setLogin(m_login);
       m_url=query.value(0).toString();
       xhr.setUrl(m_url);
       m_imagedir=query.value(3).toString();
       xhr.setImagedir(m_imagedir);
       QString isActive=query.value(7).toString();
    }
       //m_updateInterval=query.value(5).toInt(); 


    QSqlQuery syncquery("SELECT * FROM globaloptions",m_db);
//    QSqlQuery delquery("DELETE FROM globaloptions WHERE k='sync_interval'",m_db);
//    delquery.exec();
    m_updateInterval=0;
    syncindex=0;
    synclist.clear();
       //QSqlQuery syncquery("SELECT * FROM globaloptions WHERE k like 'sync_%' AND v=1",m_db);
    while (syncquery.next()){
        if (syncquery.value(0).toString()=="syncinterval"){
            m_updateInterval=syncquery.value(1).toInt();
        }
        if (syncquery.value(0).toString().left(5)=="sync_" && syncquery.value(1).toInt()==1){
            synclist.append(syncquery.value(0).toString());
            //qDebug() << " sync " << syncquery.value(0).toString() << " " <<syncquery.value(1).toString();
        }
        if (syncquery.value(0).toString().left(7)=="notify_" && syncquery.value(1).toInt()==1){
            notifylist.append(syncquery.value(0).toString());
            //qDebug() << " notify " << syncquery.value(0).toString() << " " <<syncquery.value(1).toString();
        }

    }
    QSqlQuery synctimequery("SELECT * FROM globaloptions WHERE k='lastsync'",m_db);
    if (synctimequery.next()){
        QSqlQuery synctimequery2("UPDATE globaloptions SET v='"+QString::number(QDateTime::currentSecsSinceEpoch()) + "' WHERE k = 'lastsync'",m_db);
        if(!(synctimequery2.exec())) {qDebug()<<" synctimequery2 " << synctimequery2.lastError();}
        //qDebug() << " synctimequery ";
    } else {
        //qDebug() << "INSERT INTO globaloptions(k,v) VALUES('lastsync','"+QString::number(QDateTime::currentSecsSinceEpoch()) + "'";
        QSqlQuery synctimequery3("INSERT INTO globaloptions(k,v) VALUES('lastsync','"+QString::number(QDateTime::currentSecsSinceEpoch()) + "')",m_db);
        if(!(synctimequery3.exec())) {qDebug() << " synctimequery3 " << synctimequery3.lastError();}
    }

}

void UPDATENEWS::startsync()
{        qDebug()<<"Friendiqa start syncing "<<syncindex <<" of "<<synclist.length();
    QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
    QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
    if (syncindex<synclist.length()){
        if (synclist[syncindex]=="sync_Timeline"){
             timeline();
        } else if (synclist[syncindex]=="sync_Replies") {
            replies();
        } else if (synclist[syncindex]=="sync_DirectMessages") {
            directmessages();
        } else if (synclist[syncindex]=="sync_Notifications") {
            notifications();
        } else if (synclist[syncindex]=="sync_Events") {
            events();
        }
    } else if (syncindex==synclist.length()) {
        m_api="";
        if(m_updateInterval!=0){
            syncindex=0;
            synclist.clear();
            m_db.close();
            m_db.removeDatabase(m_db.connectionName());
            QObject::disconnect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
            emit quitapp();
            alarm.setAlarm(m_updateInterval);
            m_updateInterval=0;
        }
    }
}


void UPDATENEWS::timeline()
{
    m_api="/api/statuses/friends_timeline";
    xhr.clearParams();
    xhr.setUrl(m_url);
    xhr.setApi(m_api);
    QSqlQuery query("SELECT status_id FROM news WHERE messagetype=0 AND username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db);
    if (query.isActive() && query.isSelect()){
        if (query.first()){
            QString lastid=query.value(0).toString();
            xhr.setParam("since_id",lastid);
        }
    }
    xhr.setParam("count","50");
    xhr.get();
    QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
    QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
    QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
}

void UPDATENEWS::replies()
{
    m_api="/api/statuses/replies";
    xhr.clearParams();
    xhr.setUrl(m_url);
    xhr.setApi(m_api);
    QSqlQuery query("SELECT status_id FROM news WHERE messagetype=3 AND username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db);
    if (query.isActive() && query.isSelect()){
        if (query.first()){
            QString lastid=query.value(0).toString();
            xhr.setParam("since_id",lastid);
        }
    }
    xhr.setParam("count","50");
    xhr.get();
    QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
    QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
    QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
}

void UPDATENEWS::directmessages()
{
    m_api="/api/direct_messages/all";
    xhr.clearParams();
    xhr.setUrl(m_url);
    xhr.setApi(m_api);
    QSqlQuery query("SELECT status_id FROM news WHERE messagetype=1 AND username='"+ username +"' ORDER BY status_id DESC LIMIT 1",m_db);
    if (query.isActive() && query.isSelect()){
        if (query.first()){
            QString lastid=query.value(0).toString();
            xhr.setParam("since_id",lastid);
        }
    }
    xhr.get();
    QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
    QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
    QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
}

void UPDATENEWS::notifications()
{
    m_api="/api/friendica/notifications";
    xhr.clearParams();
    xhr.setUrl(m_url);
    xhr.setApi(m_api);
    xhr.get();
    QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
    QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
    QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
}


void UPDATENEWS::events()
{
    m_api="/api/friendica/events";
    xhr.clearParams();
    xhr.setUrl(m_url);
    xhr.setApi(m_api);
    QSqlQuery query("SELECT id FROM events WHERE username='"+ username +"' ORDER BY id DESC LIMIT 1",m_db);
    if (query.isActive() && query.isSelect()){
        if (query.first()){
            QString lastid=query.value(0).toString();
            xhr.setParam("since_id",lastid);
        }
    }
    xhr.setParam("count","30");
    xhr.get();
    QObject::disconnect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(store(QByteArray,QString)));
    QObject::connect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(storeEvents(QByteArray,QString)));
    QObject::connect(&xhr,SIGNAL(error(QString,QString,QString,int)),this,SLOT(showError(QString,QString,QString,int)));
    //QObject::connect(&xhr, SIGNAL(downloaded(QString, QString, QString, int)), this, SLOT(updateImageLocation(QString,QString, QString, int)));
}


void UPDATENEWS::store(QByteArray serverreply,QString apiname)
{   if (apiname!=m_api || xhr.downloadtype()!=""){} else {
        QJsonDocument news;
        //qDebug()<<apiname << serverreply;
        QJsonParseError jsonerror;
        news=QJsonDocument::fromJson(serverreply,&jsonerror);
        if (news.isArray()){
            for (int i=0; i < news.array().count();i++){
                QJsonValue newsitem=news[i];
                try{
                    if (apiname=="/api/friendica/notifications"){
                        QSqlQuery testquery("SELECT status_id FROM news WHERE status_id=" + QString::number(newsitem["id"].toInt()) + " AND messagetype=2 AND username='"+ username +"'",m_db);
                        if (testquery.first()) {continue;}
                    }
                    QSqlQuery query(m_db);
                    query.prepare("INSERT INTO news (username,messagetype,text,created_at,in_reply_to_status_id,source,status_id,in_reply_to_user_id,geo,favorited,uid,statusnet_html,statusnet_conversation_id,friendica_activities,friendica_activities_self,attachments,friendica_owner) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
                    query.bindValue(0,username);
                    query.bindValue(1,"0");
                    query.bindValue(2, newsitem["text"].toString().toUtf8().toBase64());
                    QString sourcedate=newsitem["created_at"].toString();
                    QString formateddate=sourcedate.mid(0,3)+", "+sourcedate.mid(8,3)+sourcedate.mid(4,3)+sourcedate.mid(25,5)+sourcedate.mid(10,15);
                    query.bindValue(3,QDateTime::fromString(formateddate,Qt::RFC2822Date).toMSecsSinceEpoch() );
                    if(newsitem["in_reply_to_status_id"]!=QJsonValue::Null){query.bindValue(4, newsitem["in_reply_to_status_id"].toInt());}
                    query.bindValue(5,newsitem["source"]);
                    query.bindValue(6,newsitem["id"].toInt());
                    if(newsitem["in_reply_to_user_id"]!=QJsonValue::Null){ query.bindValue(7,newsitem["in_reply_to_user_id"].toInt());}
                    query.bindValue(8,newsitem["geo"]);
                    query.bindValue( 9, newsitem["favorited"].toInt());
                    query.bindValue(10, newsitem["user"]["id"].toInt());
                    query.bindValue(11, newsitem["statusnet_html"].toString().toUtf8().toBase64());
                    query.bindValue(12, newsitem["statusnet_conversation_id"].toInt());
                    QJsonArray likeArray;QJsonArray dislikeArray;QJsonArray attendyesArray;QJsonArray attendnoArray;QJsonArray attendmaybeArray;
                    if (newsitem.toObject().contains("friendica_activities")){
                        for (int a=0; a < newsitem["friendica_activities"]["like"].toArray().count();a++){
                            likeArray.append(newsitem["friendica_activities"]["like"][a]["url"].toString());
                        }
                        for (int b=0; b < newsitem["friendica_activities"]["dislike"].toArray().count();b++){
                            dislikeArray.append(newsitem["friendica_activities"]["dislike"][b]["url"].toString());
                        }
                        for (int c=0; c < newsitem["friendica_activities"]["attendyes"].toArray().count();c++){
                            attendyesArray.append(newsitem["friendica_activities"]["attendyes"][c]["url"].toString());
                        }
                        for (int d=0; d < newsitem["friendica_activities"]["attendno"].toArray().count();d++){
                            attendnoArray.append(newsitem["friendica_activities"]["attendno"][d]["url"].toString());
                        }
                        for (int e = 0; e < newsitem["friendica_activities"]["attendmaybe"].toArray().count();e++){
                            attendmaybeArray.append(newsitem["friendica_activities"]["attendmaybe"][e]["url"].toString());
                        }
                     }
                    QJsonArray friendica_activities; friendica_activities={likeArray,dislikeArray,attendyesArray,attendnoArray,attendmaybeArray};
                    QJsonDocument activities; activities.setArray(friendica_activities);
                    query.bindValue(13,activities.toJson(QJsonDocument::Compact).toBase64());
                    query.bindValue(14,"[]");

                    if (newsitem["attachments"]!=QJsonValue::Undefined){
                        query.bindValue(15, QJsonDocument(newsitem["attachments"].toArray()).toJson(QJsonDocument::Compact).toBase64());
                    }else {
                        query.bindValue(15, "");
                    }

                    if (newsitem["friendica_author"]!=QJsonValue::Undefined){
                        query.bindValue(16, newsitem["friendica_author"]["url"]);
                    }else {
                        query.bindValue(16, newsitem["user"]["url"]);
                       }

                    if (apiname=="/api/statuses/replies"){
                        query.bindValue(1,"3");
                    }
                    if (apiname == "/api/direct_messages/all"){
                        query.bindValue(1,"1");
                        query.bindValue(5,"Friendica");
                        if(newsitem["recipient"]["id"]!=QJsonValue::Null){ query.bindValue(7,newsitem["recipient"]["id"].toInt());}
                        query.bindValue(10, newsitem["sender_id"].toInt());
                        query.bindValue(11, newsitem["text"].toString().toUtf8().toBase64());
                        if(newsitem["friendica_parent_uri"]!=QJsonValue::Null){ query.bindValue(12,newsitem["friendica_parent_uri"]);}
                        query.bindValue(16, newsitem["sender"]["url"]);
                    }
                    if (apiname == "/api/friendica/notifications"){
                        query.bindValue(1,"2");
                        query.bindValue(3,QDateTime::fromString(newsitem["date"].toString(),"yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch());
                        query.bindValue(5,"Friendica");
                        QJsonObject cleancontact= findNotificationContact(newsitem["url"].toString());
                        query.bindValue(10, cleancontact["id"].toInt());
                        query.bindValue(11, newsitem["msg_html"].toString().toUtf8().toBase64());
                        if(newsitem["parent"]!=QJsonValue::Null){ query.bindValue(12,newsitem["parent"]);}
                        query.bindValue(16, newsitem["url"]);
                    }

                    if(!(query.exec())) {qDebug()<< "store news " << query.lastError();}

                    // notifications
                    if (apiname=="/api/statuses/friends_timeline"){
                        if(notifylist.contains("notify_Timeline")){
                            alarm.notify("Home: "+ newsitem["user"]["name"].toString(),newsitem["text"].toString(),0);
                        }
                    }
                    if (apiname=="/api/statuses/replies"){
                        if(notifylist.contains("notify_Replies")){
                            alarm.notify("Replies: "+newsitem["user"]["name"].toString(),newsitem["text"].toString(),1);
                        }
                    }
                    if (apiname=="/api/direct_messages/all"){
                        if(notifylist.contains("notify_DirectMessages")){
                            alarm.notify("DirectMessage: "+newsitem["sender"]["name"].toString(),newsitem["text"].toString(),2);
                        }
                    }
                    if (apiname=="/api/friendica/notifications"){
                        if(notifylist.contains("notify_Notifications")){
                            alarm.notify("Notification: "+newsitem["name"].toString(),newsitem["text"].toString(),3);
                        }
                    }
                }catch(...){
                    //qDebug() << "Friendiqasync Error inserting news" << newsitem["text"].toString() << "  " << newsitem.toString();

                }
            }
            QList<QJsonValue> newcontacts=findNewContacts(news);
            //qDebug()<< "new contacts count " << newcontacts.size();
            if (newcontacts.size()>0){
                updateContacts(newcontacts);
                startImagedownload();

            } else {
                if(m_updateInterval!=0){
                    syncindex+=1;
                    startsync();
                }
            }
        }
        else {
            qDebug()<< "Friendiqa updatenews error " << serverreply;
            emit this->error(m_api,QTextCodec::codecForName("utf-8")->toUnicode(serverreply));
            syncindex+=1;
            startsync();
        }
    }

}



void UPDATENEWS::updateImageLocation(QString downloadtype,QString imageurl, QString filename, int index){
    if (downloadtype=="contactlist"){
        QSqlQuery testquery("SELECT profile_image FROM contacts WHERE profile_image_url ='"+imageurl+ "' AND username = '" +username+"'",m_db);
        testquery.first();
        //qDebug()<< "update imageurl for " <<imageurl << " from " <<testquery.value(0).toString() <<" to "<< filename <<" index " << index << " newcontactnames.length " <<newcontactnames.length();
        QSqlQuery query("UPDATE contacts SET profile_image='"+ filename +"' WHERE profile_image_url ='"+imageurl+ "' AND username = '" +username+"'",m_db);
        if(!(query.exec())) {qDebug()<< "updateImagelocation " << query.lastError();}
        if (index==(newcontactnames.length()-1)){
            newcontactnames.clear();
            newcontactimagelinks.clear();
            if(m_updateInterval!=0){
                syncindex+=1;
                startsync();
            }
        }
    }
}

QJsonObject UPDATENEWS::findNotificationContact(QString contacturl){
    QSqlQuery query("SELECT id,url FROM contacts WHERE url='"+contacturl+"' AND username='"+ username+"'",m_db);
    query.first();
    QJsonObject contact{
        {"id", query.value(0).toInt()},
        {"url", query.value(1).toString()}
    };
    return contact;
}

QList <QJsonValue> UPDATENEWS::findNewContacts(QJsonDocument news){
    QSqlQuery query("SELECT profile_image_url FROM contacts",m_db);
    QList<QString> imageurls;
    while (query.next()){
        imageurls.append(query.value(0).toString());
    }
    QList<QJsonValue> newcontacts;
    //qDebug()<<"updatenews findcontacts news count "<<news.array().count();

    for (int i=0; i<news.array().count();i++){
        //main contacts
        if (news[i].toObject().contains("sender") ){
            if(imageurls.contains(news[i]["sender"]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["sender"]["profile_image_url"].toString().section('?',0,0))){
                }
            else{
                newcontacts.append(news[i]["sender"]);
                newcontactimagelinks.append(news[i]["sender"]["profile_image_url"].toString().section('?',0,0));
                newcontactnames.append(news[i]["sender"]["screen_name"].toString());
            }
        }
        if (news[i].toObject().contains("user") ){
            if(imageurls.contains(news[i]["user"]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["user"]["profile_image_url"].toString().section('?',0,0))){
            }
            else{
                newcontacts.append(news[i]["user"]);
                newcontactimagelinks.append(news[i]["user"]["profile_image_url"].toString().section('?',0,0));
                newcontactnames.append(news[i]["user"]["screen_name"].toString());
            }
        }
        //like/dislike contacts
        if (news[i].toObject().contains("friendica_activities") ){
            for (int a=0; a < news[i]["friendica_activities"]["like"].toArray().count();a++){
                if(imageurls.contains(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString().section('?',0,0))){
                    }
                else{
                    newcontacts.append(news[i]["friendica_activities"]["like"][a]);
                    newcontactimagelinks.append(news[i]["friendica_activities"]["like"][a]["profile_image_url"].toString().section('?',0,0));
                    newcontactnames.append(news[i]["friendica_activities"][a]["screen_name"].toString());
                }
            }
            for (int b=0; b < news[i]["friendica_activities"]["dislike"].toArray().count();b++){
                if(imageurls.contains(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString().section('?',0,0))){
                    }
                else{
                    newcontacts.append(news[i]["friendica_activities"]["dislike"][b]);
                    newcontactimagelinks.append(news[i]["friendica_activities"]["dislike"][b]["profile_image_url"].toString().section('?',0,0));
                    newcontactnames.append(news[i]["friendica_activities"][b]["screen_name"].toString());
                }
            }
        }
        //owner contacts
        if (news[i].toObject().contains("friendica_author") ){
            if(imageurls.contains(news[i]["friendica_author"]["profile_image_url"].toString().section('?',0,0)) || newcontactimagelinks.contains(news[i]["friendica_owner"]["profile_image_url"].toString().section('?',0,0))){
                }
            else{
                newcontacts.append(news[i]["friendica_author"]);
                newcontactimagelinks.append(news[i]["friendica_author"]["profile_image_url"].toString().section('?',0,0));
                newcontactnames.append(news[i]["friendica_author"]["screen_name"].toString());
            }
          }
    }
    return newcontacts;
}


void UPDATENEWS::updateContacts(QList<QJsonValue> contacts){
    qint64 currentTime =QDateTime::currentMSecsSinceEpoch();
    for (int i=0; i < contacts.count();i++){
        QJsonValue contact=contacts[i];
        QSqlQuery query(m_db);
        try{
            //qDebug() << "updatecontact " << contact["screen_name"];
            QSqlQuery testquery("SELECT url FROM contacts WHERE username='"+ username +"' AND url='" + contact["url"].toString() +"'",m_db);
            if (testquery.first()){
                query.prepare("UPDATE contacts SET id=?, name=?, screen_name=?, location=?,imageAge=?,"
                          "profile_image_url=?, description=?, protected=?, followers_count=?,"
                          "friends_count=?, created_at=?, favourites_count=?, utc_offset=?, time_zone=?, statuses_count=?,"
                          "following=?, verified=?, statusnet_blocking=?, notifications=?, statusnet_profile_url=?, cid=?, network=?, timestamp=? "
                          " WHERE username='"+ username +"' AND url='" + contact["url"].toString() +"'");
                query.bindValue(0, contact["id"].toInt());
                query.bindValue(1, contact["name"].toString().toUtf8().toBase64());
                query.bindValue(2, contact["screen_name"]);
                query.bindValue(3, contact["location"]);
                query.bindValue(4, currentTime);
                query.bindValue(5, contact["profile_image_url"].toString().section('?',0,0));
                if(contact["description"].isNull() ){query.bindValue(6,"");}else{query.bindValue(6, contact["description"].toString().toUtf8().toBase64());}
                query.bindValue(7,contact["protected"].toBool());
                query.bindValue(8,contact["followers_count"].toInt());
                query.bindValue(9,contact["friends_count"].toInt());
                QString sourcedate=contact["created_at"].toString();
                QString formateddate=sourcedate.mid(0,3)+", "+sourcedate.mid(8,3)+sourcedate.mid(4,3)+sourcedate.mid(25,5)+sourcedate.mid(10,15);
                query.bindValue(10,QDateTime::fromString(formateddate,Qt::RFC2822Date).toMSecsSinceEpoch() );
                query.bindValue(11,contact["favorites_count"].toInt());
                query.bindValue(12,contact["utc_offset"].toInt());
                query.bindValue(13,contact["time_zone"].toString());
                query.bindValue(14,contact["statuses_count"].toInt());
                query.bindValue(15,contact["following"].toBool());
                query.bindValue(16,contact["verfied"].toBool());
                query.bindValue(17,contact["statusnet_blocking"].toBool());
                query.bindValue(18,contact["notifications"].toBool());
                query.bindValue(19,contact["statusnet_profile_url"]);
                query.bindValue(20,contact["cid"].toInt());
                query.bindValue(21,contact["network"]);
                qint64 timestamp=0;
                QString timestamphelper=contact["profile_image_url"].toString();
                try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){}
                query.bindValue(22,timestamp);
            }

            else{
                query.prepare("INSERT INTO contacts (username, id, name, screen_name, location,imageAge,"
                          "profile_image_url, description, profile_image, url, protected, followers_count,"
                          "friends_count, created_at, favourites_count, utc_offset, time_zone, statuses_count,"
                          "following, verified, statusnet_blocking, notifications, statusnet_profile_url, cid, network, isFriend, timestamp)"
                          "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");

                query.bindValue(0,username);
                query.bindValue(1, contact["id"].toInt());
                query.bindValue(2, contact["name"].toString().toUtf8().toBase64());
                query.bindValue(3, contact["screen_name"]);
                query.bindValue(4, contact["location"]);
                query.bindValue(5, currentTime);
                query.bindValue(6, contact["profile_image_url"].toString().section('?',0,0));
                if(contact["description"].isNull() ){query.bindValue(7,"");}else{query.bindValue(7, contact["description"].toString().toUtf8().toBase64());}
                query.bindValue(8,"none");
                query.bindValue(9, contact["url"].toString());
                query.bindValue(10,contact["protected"].toBool());
                query.bindValue(11,contact["followers_count"].toInt());
                query.bindValue(12,contact["friends_count"].toInt());
                QString sourcedate=contact["created_at"].toString();
                QString formateddate=sourcedate.mid(0,3)+", "+sourcedate.mid(8,3)+sourcedate.mid(4,3)+sourcedate.mid(25,5)+sourcedate.mid(10,15);
                query.bindValue(13,QDateTime::fromString(formateddate,Qt::RFC2822Date).toMSecsSinceEpoch() );
                query.bindValue(14,contact["favorites_count"].toInt());
                query.bindValue(15,contact["utc_offset"].toInt());
                query.bindValue(16,contact["time_zone"].toString());
                query.bindValue(17,contact["statuses_count"].toInt());
                query.bindValue(18,contact["following"].toBool());
                query.bindValue(19,contact["verified"].toBool());
                query.bindValue(20,contact["statusnet_blocking"].toBool());
                query.bindValue(21,contact["notifications"].toBool());
                query.bindValue(22,contact["statusnet_profile_url"]);
                query.bindValue(23,contact["cid"].toInt());
                query.bindValue(24,contact["network"]);
                query.bindValue(25, 0);
                qint64 timestamp=0;
                QString timestamphelper=contact["profile_image_url"].toString();
                try {timestamp=timestamphelper.mid(timestamphelper.indexOf("?ts")+4,timestamphelper.length()).toUInt();} catch(...){}
                query.bindValue(26,timestamp);

            }
            if(!(query.exec())) {qDebug()<< "updatecontacts " << query.lastError();}
        } catch(...){
            qDebug() << "Friendiqasync Error inserting contact" << contact["screen_name"] << "  " << contact.toString();
        }
    }
}


void UPDATENEWS::storeEvents(QByteArray serverreply,QString apiname)
{  if (apiname!=m_api || xhr.downloadtype()!=""){} else {
        QJsonDocument events;
        //qDebug()<<apiname << serverreply;
        QJsonParseError jsonerror;
        events=QJsonDocument::fromJson(serverreply,&jsonerror);
        if (events.isArray()){
            for (int i=0; i < events.array().count();i++){
                QJsonValue eventitem=events[i];
                try{
                    QSqlQuery query(m_db);
                    query.prepare("INSERT INTO events (username,id,cid,start,end,title,uri,desc,location,type,nofinish,adjust,ignore,permissions) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
                    query.bindValue(0,username);
                    query.bindValue(1,eventitem["id"].toInt());
                    query.bindValue(2,eventitem["cid"].toInt());
                    QString sourcedateStart=eventitem["startTime"].toString();
                    query.bindValue(3,QDateTime::fromString(sourcedateStart,Qt::ISODate).toMSecsSinceEpoch() );
                    QString sourcedateEnd=eventitem["endTime"].toString();
                    query.bindValue(4,QDateTime::fromString(sourcedateEnd,Qt::ISODate).toMSecsSinceEpoch() );
                    query.bindValue(5,eventitem["name"].toString());
                    query.bindValue(6,eventitem["uri"].toString());
                    query.bindValue(7,eventitem["desc"].toString().toUtf8().toBase64());
                    query.bindValue(8,eventitem["place"].toString());
                    query.bindValue(9,eventitem["type"].toString());
                    query.bindValue(10,eventitem["nofinsh"].toInt());
                    query.bindValue(11,eventitem["adjust"].toInt());
                    query.bindValue(12,eventitem["ignore"].toInt());
                    QJsonArray permissions; permissions={eventitem["allow_cid"].toString().replace("<","[").replace(">","]"),eventitem["allow_gid"].toString().replace("<","[").replace(">","]"),eventitem["deny_cid"].toString().replace("<","[").replace(">","]"),eventitem["deny_gid"].toString().replace("<","[").replace(">","]")};
                    QJsonDocument permissionDocument; permissionDocument.setArray(permissions);
                    query.bindValue(13,permissionDocument.toJson(QJsonDocument::Compact));
                    if(!(query.exec())) {qDebug()<< "store events " << query.lastError();}
                    } catch(...){
                        qDebug() << "Friendiqasync Error event" << eventitem["name"];
                    }
            }
        emit this->success(m_api);
        }
    }
    if(notifylist.contains("notify_Events")){
        QSqlQuery eventnotifyquery("SELECT start,title FROM events WHERE (start BETWEEN " + QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch()) + " AND "+QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch()+(m_updateInterval*60*1000))+") AND username='"+ username +"'",m_db);
            while (eventnotifyquery.next()) {
                alarm.notify("Event: "+ QDateTime::fromMSecsSinceEpoch(eventnotifyquery.value(0).toLongLong()).toString("dd.MM.yyyy hh:mm"),eventnotifyquery.value(1).toString(),1);
            }
    }
    if(m_updateInterval!=0){
        syncindex+=1;
        startsync();
    }
    QObject::disconnect(&xhr,SIGNAL(success(QByteArray,QString)),this,SLOT(storeEvents(QByteArray,QString)));
}

QString UPDATENEWS::url() const
{
    return m_url;
}

void UPDATENEWS::startImagedownload()
{
    //qDebug() << "start image download";
    xhr.setDownloadtype("contactlist");
    xhr.setFilelist(newcontactimagelinks);
    xhr.setContactlist(newcontactnames);
    xhr.setImagedir(m_imagedir);
    xhr.getlist();
}

void UPDATENEWS::showError(QString data, QString url,QString api, int code )
{
    //qDebug() << "showerror " << api << " data " << data;
    emit this->error(api,data);
    if (api!=m_api || xhr.downloadtype()!=""){} else{
        if(m_updateInterval!=0){
            syncindex+=1;
            startsync();
        }
    }
}