<?php

/**
 * SyncModel
 *
 */
class SyncModel
{
    public static function getJobs($limit,$type = 'create')
    {
        $limit = (int) $limit;
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();

        switch ($type)
        {
            case 'create':
                $sql = "SELECT SQL_CALC_FOUND_ROWS
                               O.id         AS id,
                               O.type       AS type,
                               O.title      AS title,
                               O.detail     AS detail,
                               O.tags       AS tags,
                               O.price      AS price,
                               O.currency   AS currency,
                               O.unit       AS unit,
                               O.image      AS image,
                               O.cat1       AS cat1,
                               O.cat2       AS cat2,
                               O.cat3       AS cat3,
                               O.zipcode    AS zipcode,
                               O.created    AS created,
                               O.modified   AS modified,
                               P.uuid       AS recipient_uuid
                        FROM `".$prefix."offers` AS O
                        INNER JOIN `".$prefix."platforms` AS P
                        LEFT JOIN `".$prefix."category_platforms` AS OS ON OS.send = P.id
                        LEFT JOIN `".$prefix."category_platforms` AS RR ON RR.remote_receive = P.id
                        WHERE (O.id, P.id)
                        NOT IN (SELECT data_id, platform_id
                                FROM `".$prefix."sync_log`)
                          AND P.status = '3'
                          AND O.external = '0'
                          AND O.status = '3'
                          AND O.cat2 = OS.cat2
                          AND O.cat2 = RR.cat2
                        ORDER BY rand()
                        LIMIT :limit";
                break;
            case 'update':
                $sql = "SELECT SQL_CALC_FOUND_ROWS
                               O.id         AS id,
                               O.type       AS type,
                               O.title      AS title,
                               O.detail     AS detail,
                               O.tags       AS tags,
                               O.price      AS price,
                               O.currency   AS currency,
                               O.unit       AS unit,
                               O.image      AS image,
                               O.cat1       AS cat1,
                               O.cat2       AS cat2,
                               O.cat3       AS cat3,
                               O.zipcode    AS zipcode,
                               O.created    AS created,
                               O.modified   AS modified,
                               P.uuid       AS recipient_uuid
                        FROM `".$prefix."offers` AS O
                        INNER JOIN `".$prefix."platforms` AS P
                        WHERE (O.id, P.id)
                           IN (SELECT data_id, platform_id
                                FROM `".$prefix."sync_log`)
                          AND (O.id, P.id, O.modified)
                        NOT IN (SELECT data_id, platform_id, last_changed
                                FROM `".$prefix."sync_log`)
                          AND P.status = '3'
                          AND O.external = '0'
                          AND O.status = '3'
                        ORDER BY rand()
                        LIMIT :limit";
                break;
            case 'delete':
                $sql = "SELECT SQL_CALC_FOUND_ROWS
                               L.data_id    AS id,
                               NULL         AS type,
                               NULL         AS title,
                               NULL         AS detail,
                               NULL         AS tags,
                               NULL         AS price,
                               NULL         AS currency,
                               NULL         AS unit,
                               NULL         AS image,
                               NULL         AS cat1,
                               NULL         AS cat2,
                               NULL         AS cat3,
                               NULL         AS zipcode,
                               NULL         AS created,
                               NULL         AS modified,
                               P.uuid       AS recipient_uuid
                        FROM `".$prefix."sync_log` AS L
                        LEFT JOIN `".$prefix."platforms` AS P ON P.id = L.platform_id
                        LEFT JOIN `".$prefix."offers` AS O ON O.id = L.data_id
                        LEFT JOIN `".$prefix."category_platforms` AS C
                            ON C.send = L.platform_id
                           AND C.cat2 = O.cat2
                        LEFT JOIN `".$prefix."category_platforms` AS RR
                            ON RR.remote_receive = L.platform_id
                           AND RR.cat2 = O.cat2
                        WHERE (O.title IS NULL
                               AND P.status = 3
                               AND P.id = L.platform_id
                               AND O.id != 0)
                           OR (C.cat2 IS NULL
                               AND O.id != 0
                               AND (P.status = 3
                                    OR P.status = 4))
                           OR (RR.cat2 IS NULL
                               AND O.id != 0
                               AND (P.status = 3
                                    OR P.status = 4))
                           OR (O.id IS NULL
                               AND L.data_id != 0)
                        GROUP BY id
                        ORDER BY rand()
                        LIMIT :limit";
                break;
        }

        $query = $database->prepare($sql);
        $query->bindParam(':limit', $limit, PDO::PARAM_INT);
        $query->execute();

        $results = array();
        $results['total_left'] = $database->query("SELECT FOUND_ROWS()")->fetchColumn();

        $results['data'] = array();
        if ($query->rowCount() > 0)
        {
            $data = array(); $i = 0;
            foreach($query->fetchAll() as $offer)
            {
                $data[$i]                   = new stdClass();
                $data[$i]->id               = $offer->id;
                if ($type != 'delete')
                {
                    $data[$i]->type         = $offer->type;
                    $data[$i]->title        = $offer->title;
                    $data[$i]->detail       = $offer->detail;
                    $data[$i]->tags         = $offer->tags;
                    $data[$i]->price        = $offer->price;
                    $data[$i]->currency     = $offer->currency;
                    $data[$i]->unit         = $offer->unit;
                    $data[$i]->image        = $offer->image;
                    $data[$i]->cat1         = $offer->cat1;
                    $data[$i]->cat2         = $offer->cat2;
                    $data[$i]->cat3         = $offer->cat3;
                    $data[$i]->zipcode      = $offer->zipcode;
                    $data[$i]->created      = $offer->created;
                    $data[$i]->modified     = $offer->modified;
                }
                $data[$i]->recipient_uuid   = $offer->recipient_uuid;
                $data[$i]->api_call_type    = $type;
                $i++;
            }
            $results['data'] = $data;
        }
        return $results;
    }

    public static function getPlatformUpdates($limit)
    {
        $limit = (int) $limit;
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $sql = "SELECT SQL_CALC_FOUND_ROWS
                       P.id                 AS id,
                       P.uuid               AS recipient_uuid,
                       P.modified           AS modified,
                       'platform_update'    AS api_call_type
                FROM `".$prefix."platforms` AS P
                WHERE (P.id, P.modified)
                NOT IN (SELECT platform_id, last_changed
                        FROM `".$prefix."sync_log`)
                  AND P.status = '3'
                ORDER BY rand()
                LIMIT :limit";
        $query = $database->prepare($sql);
        $query->bindParam(':limit', $limit, PDO::PARAM_INT);
        $query->execute();
        $results = array();
        $results['total_left'] = $database->query("SELECT FOUND_ROWS()")->fetchColumn();

        if ($query->rowCount() > 0)
        {
            $data = array();
            $i = 0;
            foreach ($query->fetchAll() as $update)
            {
                $data[$i] = new stdClass();
                $data[$i]->id               = $update->id;
                $data[$i]->recipient_uuid   = $update->recipient_uuid;
                $data[$i]->name             = Config::getFromDB('MarketName');
                $data[$i]->location         = Config::getFromDB('MarketAddressZipcode').' '.
                                              Config::getFromDB('MarketAddressCity');
                $data[$i]->short_info       = Config::getFromDB('MarketDetailShort');
                $data[$i]->receive          = ConnectionsModel::getCategoryConnections('receive',
                                                                                       $update->id,
                                                                                       'cat2',
                                                                                       'string');
                $data[$i]->modified         = $update->modified;
                $data[$i]->api_call_type    = $update->api_call_type;
                $i++;
            }

            $results['data'] = $data;
        }
        return $results;
    }

    private static function getMailJobs($limit)
    {
        $limit = (int) $limit;
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $sql = "SELECT SQL_CALC_FOUND_ROWS
                       id,
                       email,
                       subject,
                       body
                FROM `".$prefix."mails`
                WHERE send_try < 3
                ORDER BY send_try ASC
                LIMIT :limit";
        $query = $database->prepare($sql);
        $query->bindParam(':limit', $limit, PDO::PARAM_INT);
        $query->execute();
        $results = array();
        $results['total_left'] = $database->query("SELECT FOUND_ROWS()")->fetchColumn();

        if ($query->rowCount() > 0)
        {
            $data = array();
            $i = 0;
            foreach ($query->fetchAll() as $mail)
            {
                $data[$i]           = new stdClass();
                $data[$i]->id       = $mail->id;
                $data[$i]->email    = $mail->email;
                $data[$i]->subject  = $mail->subject;
                $data[$i]->body     = $mail->body;
                $i++;
            }
            $results['data'] = $data;
        }
        return $results;
    }

    public static function getStatisticsJobs()
    {
        $statistics = array();
        if (Config::getFromDB('MarketShareStatistics') != 0 &&
        (time() - Config::getFromDB('MarketStatisticsLastSync')) > 60*60*24)
        {
            $statistics['total_left'] = 1;
            $details = ConnectionsModel::getPlatformDetailsByID(Config::getFromDB('MarketShareStatistics'));
            if ($details == false || $details->status != 3)
            {
                $statistics['total_left'] = 0;
            } else {
                $data = array();
                $data[0] = new stdClass();
                $data[0]->recipient_uuid = $details->uuid;
                $data[0]->users = Helper::getTotalNumberOfUsers();
                $data[0]->offers = Helper::getTotalNumberByType(1);
                $data[0]->requests = Helper::getTotalNumberByType(2);
                $data[0]->connections = Helper::getTotalNumberOfConnections();
                $data[0]->searches = Helper::getTotalNumberOfSearches();
                $data[0]->api_call_type = 'statistics';
                $data[0]->own_uuid = ConnectionsModel::getOwnUUID();
                $statistics['data'] = $data;
            }

        } else {
            $statistics['total_left'] = 0;
        }
        return $statistics;
    }

    public static function processMailJobs($limit = 5)
    {
        $mailJobs = self::getMailJobs($limit);
        $result = new stdClass();
        $result->total = $mailJobs['total_left'];
        $success = 0; $failed = 0;
        if ($mailJobs['total_left'] > 0)
        {
            $mail = new Mail;
            foreach ($mailJobs['data'] as $mailJob)
            {
                $mail_sent = $mail->sendMail($mailJob->email,
                                             Config::getFromDB('MarketContactEmail'),
                                             Config::getFromDB('MarketName'),
                                             $mailJob->subject,
                                             $mailJob->body
                );

                if ($mail_sent)
                {
                    self::deleteSentMail($mailJob->id);
                    $success++;
                }
                else
                {
                    self::oneUpSendTry($mailJob->id);
                    $failed++;
                }
            }
            $result->sent = $success;
            $result->failed = $failed;
        }
        $result->mails = $success + $failed;
        return $result;
    }

    private static function deleteSentMail($id)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $sql = "DELETE FROM `".$prefix."mails`
                WHERE id = :id
                LIMIT 1";
        $query = $database->prepare($sql);
        $query->bindParam(':id', $id, PDO::PARAM_INT);
        $query->execute();
    }

    private static function oneUpSendTry($id)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $sql = "UPDATE `".$prefix."mails`
                SET send_try = send_try + 1
                WHERE id = :id
                LIMIT 1";
        $query = $database->prepare($sql);
        $query->bindParam(':id', $id, PDO::PARAM_INT);
        $query->execute();
    }

    public static function combineJobs($limit)
    {
        $jobs_mail              = self::getMailJobs($limit);
        $jobs_platform_update   = self::getPlatformUpdates($limit);
        $jobs_create            = self::getJobs($limit,'create');
        $jobs_update            = self::getJobs($limit,'update');
        $jobs_delete            = self::getJobs($limit,'delete');
        $jobs_statistics        = self::getStatisticsJobs();

        $jobs = array();
        $jobs['total_left'] = $jobs_mail['total_left'] +
                              $jobs_platform_update['total_left'] +
                              $jobs_create['total_left'] +
                              $jobs_update['total_left'] +
                              $jobs_delete['total_left'] +
                              $jobs_statistics['total_left'];
        if ($jobs['total_left'] < 1)
        {
            return $jobs;
        }
        else
        {
            $jobs['data'] = array();
            $jobs = self::addJobs($jobs,$jobs_platform_update,$limit);
            $jobs = self::addJobs($jobs,$jobs_create,$limit);
            $jobs = self::addJobs($jobs,$jobs_update,$limit);
            $jobs = self::addJobs($jobs,$jobs_delete,$limit);
            $jobs = self::addJobs($jobs,$jobs_statistics,$limit);
        }
        return $jobs;
    }

    private static function addJobs($jobs,$jobsToAdd,$limit)
    {
        if (count($jobs['data']) >= $limit || $jobsToAdd['total_left'] == 0)
        {
            return $jobs;
        }
        foreach ($jobsToAdd['data'] as $addJob)
        {
            $jobs['data'][] = $addJob;
            if (count($jobs['data']) >= $limit)
            {
                return $jobs;
            }
        }
        return $jobs;
    }

    public static function processJobs($limit,$type = 'create')
    {
        $jobs = self::combineJobs($limit);

        $results = array();
        if ($jobs['total_left'] > 0)
        {
            $results['totalJobs'] = $jobs['total_left'];
            $successfullySynced = 0;
            foreach ($jobs['data'] as $data)
            {
                $platform               = new stdClass();

                if (in_array($data->api_call_type,array('create','update')))
                {
                    $data->external_url = ConnectionsModel::getOwnPlatformURL()
                                                    ."offers/view/".$data->id;
                }

                if (isset($data->image) && !is_null($data->image))
                {
                    $data->image        = ConnectionsModel::getOwnPlatformURL()
                                                    ."data/".$data->image;
                }

                $data->own_uuid         = ConnectionsModel::getOwnUUID();
                $data->timestamp        = time();
                $platform->uuid         = $data->recipient_uuid;
                $platform->id           = ConnectionsModel::getPlatformIDByUUID($platform->uuid);
                switch ($data->api_call_type)
                {
                    case 'create':
                        $callType = 'POST';
                        $extPath = 'offers';
                        break;
                    case 'update':
                        $callType = 'PUT';
                        $extPath = 'offers/'.$data->id;
                        break;
                    case 'platform_update':
                        $callType = 'PUT';
                        $extPath = 'platforms/'.$data->own_uuid;
                        $data->id = 0;
                        break;
                    case 'delete':
                        $callType = 'DELETE';
                        $extPath = 'offers/'.$data->id;
                        break;
                    case 'statistics':
                        $callType = 'POST';
                        $extPath = 'statistics/'.$data->own_uuid;
                        break;
                }
                $platform->url          = ConnectionsModel::getRemoteURLByUUID($platform->uuid)
                                                            ."api/".$extPath;

                $data_json              = json_encode($data);

                $encrypted_data         = ConnectionsModel::encryptData($data_json,
                                                                        $platform->uuid);
                $signature              = ConnectionsModel::signData($encrypted_data,
                                                                     $platform->uuid);

                $result_json = ConnectionsModel::postToApi($platform->url,
                                                           $encrypted_data,
                                                           $signature,
                                                           $data->timestamp,
                                                           $callType);

                $result = json_decode($result_json);
                $results['errorCode'] = '';
                $results['errorMessage'] = '';
                if (isset($result->status) && $result->status == "success")
                {
                    switch ($data->api_call_type) {
                        case 'delete':
                            $status = self::deleteFromLog($data->id,
                                                          $platform->id);
                            break;
                        case 'statistics':
                            AdminModel::updateSettings('MarketStatisticsLastSync',
                                                       'value_int',
                                                       time());
                            break;
                        default:
                            $status = self::saveToLog($data->id,
                                                      $data->modified,
                                                      $platform->id);
                            break;
                    }
                    $successfullySynced++;
                    self::updateSuccessfulSyncStatus($platform->id);
                }
                else
                {
                    if (isset($result->error->code))
                    {
                        $results['errorCode'] .= $result->error->code;
                    }
                    if (isset($result->error->message))
                    {
                        $results['errorMessage'] .= $result->error->message;
                    }
                    self::incrementFailedSyncCounter($platform->id);
                    if (self::getFailedSyncCounter($platform->id) >= 50)
                    {
                        if (self::getPlatformStatus($platform->id) == 4)
                        {
                            self::deletePlatformConnection($platform->id);
                        }
                        else
                        {
                            self::setPlatformStatus($platform->id, 'paused');
                            $details = ConnectionsModel::getPlatformDetailsByID($platform->id);
                            $email = new stdClass();
                            $email->address = Config::getFromDB('MarketAdminEmail');
                            $email->subject = '['.Config::getFromDB('MarketName').
                            '] Eine Plattformverbindung wurde automatisch Pausiert';
                            $email->body = "Die Plattformverbindung mit ".
                            $details->name." wurde Pausiert da die letzten 50 ".
                            "synchronisierungsversuche fehlgeschlagen sind.\n\n".
                            "Bitte überprüfen Sie, ob die Plattform weiterhin unter ".
                            "nachfolgender URL erreichbar ist und kontaktieren Sie ".
                            "gegebenenfalls den Administrator.\n\n".
                            $details->url;
                            $mail = new Mail;
                            $mail->insertEmailToSend($email);
                        }
                    }
                }
            }
            $results['successfullySynced'] = $successfullySynced;
            $results['totalJobsLeft'] = $results['totalJobs'] - $successfullySynced;
            if ($successfullySynced == count($jobs['data']))
            {
                $results['status'] = 'success';
            }
            else
            {
                $results['status'] = 'error';
                $results['message'] = $results['errorCode'].' '.$results['errorMessage']
                    .' data: '.$result_json;
            }
        }
        else
        {
            $results['status'] = 'done';
        }
        return $results;
    }

    private static function saveToLog($data_id,$last_changed,$platform_id)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $query = $database->prepare("INSERT INTO `".$prefix."sync_log`
                                        (data_id,
                                         platform_id,
                                         last_changed,
                                         timestamp)
                                     VALUES
                                        (:data_id,
                                         :platform_id,
                                         :last_changed,
                                         NOW())");
        $query->bindParam(':data_id',       $data_id,       PDO::PARAM_INT);
        $query->bindParam(':platform_id',   $platform_id,   PDO::PARAM_INT);
        $query->bindParam(':last_changed',  $last_changed,  PDO::PARAM_STR);
        if ($query->execute() && $query->rowCount() > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private static function deleteFromLog($data_id,$platform_id)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $query = $database->prepare("DELETE
                                     FROM `".$prefix."sync_log`
                                     WHERE data_id = :data_id
                                       AND platform_id = :platform_id");
        $query->bindParam(':data_id',       $data_id,       PDO::PARAM_INT);
        $query->bindParam(':platform_id',   $platform_id,   PDO::PARAM_INT);
        if ($query->execute() && $query->rowCount() > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private static function updateSuccessfulSyncStatus($platformID)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $query = $database->prepare("UPDATE `".$prefix."platforms`
                                     SET last_successful_sync = NOW(),
                                         failed_sync_count = 0
                                     WHERE id = :platform_id");
        $query->bindParam(':platform_id',   $platformID,   PDO::PARAM_INT);
        if ($query->execute() && $query->rowCount() > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private static function incrementFailedSyncCounter($platformID)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $query = $database->prepare("UPDATE `".$prefix."platforms`
                                     SET failed_sync_count = failed_sync_count + 1
                                     WHERE id = :platform_id");
        $query->bindParam(':platform_id',   $platformID,   PDO::PARAM_INT);
        if ($query->execute() && $query->rowCount() > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private static function getFailedSyncCounter($platformID)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $sql = "SELECT failed_sync_count
                FROM `".$prefix."platforms`
                WHERE id = :platform_id";
        $query = $database->prepare($sql);
        $query->bindParam(':platform_id',   $platformID,   PDO::PARAM_INT);
        if ($query->execute() && $query->rowCount() > 0)
        {
            return $query->fetch()->failed_sync_count;
        }
        else
        {
            return false;
        }
    }

    private static function getPlatformStatus($platformID)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $query = $database->prepare("SELECT status
                                     FROM `".$prefix."platforms`
                                     WHERE id = :platform_id");
        $query->bindParam(':platform_id',   $platformID,   PDO::PARAM_INT);
        if ($query->execute() && $query->rowCount() > 0)
        {
            return $query->fetch()->status;
        }
        else
        {
            return false;
        }
    }

    private static function setPlatformStatus($platformID, $status)
    {
        switch ($status)
        {
            case 'paused':
                $status = 2;
                break;
            case 'connected':
                $status = 3;
                break;
            case 'deleted':
                $status = 4;
                break;
            default:
                $status = 2;
        }
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $query = $database->prepare("UPDATE `".$prefix."platforms`
                                     SET status = :status
                                     WHERE id = :platform_id");
        $query->bindParam(':status',        $status,       PDO::PARAM_INT);
        $query->bindParam(':platform_id',   $platformID,   PDO::PARAM_INT);
        if ($query->execute() && $query->rowCount() > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private static function deletePlatformConnection($platformID)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $query = $database->prepare("DELETE FROM `".$prefix."platforms`
                                     WHERE id = :platform_id");
        $query->bindParam(':platform_id',   $platformID,   PDO::PARAM_INT);
        if ($query->execute() && $query->rowCount() > 0)
        {
            return true;
        } else {
            return false;
        }
    }

    public static function checkSyncStatus()
    {
        $limit = 10;
        $response['status'] = 'waiting';
        $response['backoff'] = 10 + rand(0,10);
        $syncInProgress = Config::getFromDB('MarketSyncInProgress');
        if ($syncInProgress === false)
        {
            InstallModel::insertSetting('MarketSyncInProgress','value_int',0);
            $syncInProgress = 0;
        }

        if ($syncInProgress == 0)
        {
            $nextSync = Config::getFromDB('MarketNextSync');
            if ($nextSync === false)
            {
                $nextSync = time()+180;
                InstallModel::insertSetting('MarketNextSync','value_int',$nextSync);
            }

            $nextSyncInSeconds = $nextSync - time();
            if ($nextSyncInSeconds > 0)
            {
                $syncMessage = 'next sync in '.$nextSyncInSeconds.' seconds!';
                $response['backoff'] = $nextSyncInSeconds + rand(0,10);
            }
            else
            {
                $syncMessage = '';
            }

            if ($nextSyncInSeconds <= 0)
            {
                $syncMessage .= ' starting sync...';
                AdminModel::updateSettings('MarketSyncInProgress','value_int',1);
                $syncMessage .= ' syncing...';
                $sendMail = self::processMailJobs($limit/2);
                if ($sendMail->mails > 0)
                {
                    $syncMessage .= ' sent '.$sendMail->mails.' mails...';
                }

                $limit = $limit - $sendMail->mails;
                $syncStatus = self::processJobs($limit);
                if ($syncStatus['status'] == 'error')
                {
                    $response['status'] = 'error';
                    $syncMessage .= ' '.$syncStatus['message'];
                    AdminModel::updateSettings('MarketSyncInProgress','value_int',0);
                }
                else
                {
                    if ($syncStatus['status'] == 'done')
                    {
                        $syncMessage .= ' nothing to sync.';
                        $syncMessage .= ' setting next sync to 60 seconds.';
                        AdminModel::updateSettings('MarketNextSync','value_int',time()+60);
                        $response['backoff'] = 60 + rand(0,10);
                    }
                    else
                    {
                        $syncMessage .= ' synced '.$syncStatus['successfullySynced'].
                                        ' of '.$syncStatus['totalJobs'].' items.';
                        if ($syncStatus['successfullySynced'] == $syncStatus['totalJobs'])
                        {
                            $nextSync = 60;
                        }
                        else
                        {
                            $nextSync = 10;
                        }
                        AdminModel::updateSettings('MarketNextSync','value_int',time() + $nextSync);
                        $response['backoff'] = $nextSync + rand(0,10);
                    }
                    AdminModel::updateSettings('MarketSyncInProgress','value_int',0);
                    $response['status'] = 'success';
                }
            }
        }
        else
        {
            $syncMessage = 'sync in progress!';
            $nextSync = Config::getFromDB('MarketNextSync');
            if ((time() - $nextSync) > 300)
            {
                $syncMessage .= ' something went wrong, resetting in progress status.';
                AdminModel::updateSettings('MarketSyncInProgress','value_int',0);
            }
        }
        $response['message'] = $syncMessage;
        return $response;
    }
}
