// 7_pip.js
// This file retrieves an image uses Picture in Picture functionality

// Includes
var request = require('request');
var http = require('http');
var fs = require('fs');
var crypto = require('crypto');
http.globalAgent.maxSockets = 1000;

// Configuration
var api_url = 'https://v4.alphapicture.com';
var api_username = 'your_username_here';
var api_password = 'your_password_here';

var filename = 'example.jpg';

// Code

var requestBody = {
    "Images" : [{
        "MotifId" : "633",
        "AlternativeId" : "2",
        "Template" : {
            '1' : "%firstname%"
        },
        "Filename" : "7_%number%",
        "Dimensions" : {
            "w" : "1000",
            "h" : "750"
        },
        "Watermark" : false,
        "BadWordFilter" : false
    }],
    "OutputOptions" : {
        "OutputMethod" : "ZIP"
    },
    "Data" : [{
        "firstname" : "AlphaPicture",
        "number" : "1"
    }]
};

function Thread() {
    this.uploadImage(filename);
}

Thread.prototype = {
    uploadImage: function(filename) {
        var body = fs.readFileSync('./example.jpg');
        request({
            uri : api_url + '/SaveImage',
            method : "POST",
            headers : {
                'APIV4-Account' : api_username,
                'APIV4-Password' : api_password,
            },
            body: body,
            encoding: null,
            timeout : 60000
        }, (function(error, response, body) {
            if (error) {
                console.log('Error uploading file', error);
                process.exit();
            } else {
                var response = JSON.parse(body);
                if (response.Key) {
                    requestBody['Images'][0]['PictureInPicture'] = response.Key;
                    console.log(requestBody);
                    this.doRequest();
                }
            }
        }).bind(this));
    },
    doRequest : function() {
        request({
            uri : api_url + '/Job',
            method : "POST",
            headers : {
                'APIV4-Account' : api_username,
                'APIV4-Password' : api_password,
            },
            json : requestBody,
            timeout : 60000
        }, (function(error, response, body) {
            //console.log(this.id, 'CALLBACK')
            if (!error && response.statusCode == 200 && typeof body == 'object' && body.Error != true) {
                this.startTime = +new Date();
                this.lastRequest = body.JobId;
                console.log('Got JobId', this.lastRequest);
                console.log(body);
                this.checkIfDone();
            } else {
                console.log('Error requesting job', error, JSON.stringify(body));
            }
        }).bind(this));
    },
    checkIfDone : function() {
        var checkRequestBody = {
            Id : this.lastRequest
        };
        request({
            uri : api_url + '/JobInfo',
            method : "POST",
            headers : {
                'APIV4-Account' : api_username,
                'APIV4-Password' : api_password,
            },
            json : checkRequestBody
        }, (function(error, response, body) {
            if (error) {
                console.log('Error in checkIfDone: ' + error);
            } else {
                console.log('body', body);
                if (body.Status != 'DONE' && body.Status != 'ERROR') {
                    setTimeout((this.checkIfDone).bind(this), 2000);
                } else {
                    if (body.Status == 'DONE') {
                        this.endTime = +new Date();
                        this.totalTime = this.endTime - this.startTime;
                        console.log(this.lastRequest, 'took', this.totalTime, 'ms', 'retrieving now by key', body.Key);
                        request(api_url + '/Result/' + body.Key).pipe(fs.createWriteStream('./output/7_' + body.JobId + '.zip'));
                    } else {
                        console.log('Error occured', body);
                    }
                }
            }
        }).bind(this));
    }
}

new Thread();
