'use strict';

var method = require('./../method');
var assign = require('lodash.assign');

/**
 * @memberof jobs
 * @method logs
 * @description Stream the logs for the job with the given id, while the job is running or after it has stopped.
 * @param {object} params - Job logs parameters
 * @param {string} params.jobId - Id of the job to logs
 * @param {function} cb - Node-style error-first callback function
 * @returns logs - The job logs
 * @example
 * paperspace.jobs.logs({
 *   jobId: 'j123abc',
 * }, function(err, resp) {
 *   // handle error or http response
 * });
 * @example
 * $ paperspace jobs logs \
 *     --jobId "j123abc"
 * @example
 * # HTTP request:
 * https://api.paperspace.io
 * GET /jobs/getLogs?jobId=j123abc
 * x-api-key: 1ba4f98e7c0...
 * # Returns 200 on success
 */

 function printLogs(data) {
   var body = [];
   var line = 0;
   var eof = false;
	 if (data && data.text && data.text.length) {
		 try {
			 body = JSON.parse(data.text);
		 } catch (e) {
			 console.error(e);
			 body = [];
		 }
		 body.forEach(function itemFunc(item) {
       if (item.line) line = item.line;
       if (item.message) {
         if (item.message === 'PSEOF') eof = true;
         else console.log(item.message);
       }
		 });
	 }
   return { count: body.length, line: line, eof: eof };
 }

function logs(params, cb) {
	var tail = false;
	if (params.tail) {
		tail = true;
		delete params.tail
	}
	if (!params.line) params.line = 0;
	return _logs(params, cb);
}

function _logs(params, cb) {
	return method(logs, params, function logsCb(err, data) {
    if (err) cb(err);
    var result = printLogs(data);
    if (result.count > 0 && !result.eof) {
      result.line += 1;
      params.line = result.line;
      return _logs(params, cb);
    }
    return cb(null);
	});
}

assign(logs, {
	auth: true,
	group: 'jobs',
	name: 'logs',
	method: 'get',
	route: '/jobs/logs',
	requires: {
		jobId: 'string',
	},
	returns: {},
});

module.exports = logs;

@@ -336,24 +336,134 @@
 job to logs%0A
+ * @param %7Bboolean%7D %5Bparams.tail%5D - Optional; if tail is specified logs will be streamed until the job stops.%0A
  * @param %7Bf
@@ -1560,16 +1560,35 @@
 ne = 0;%0A
+  var backoff = 0;%0A
 %09return 
@@ -1605,14 +1605,57 @@
 ms, 
-cb);%0A%7D
+backoff, tail, cb);%0A%7D%0A%0Avar MAX_BACKOFF_SECS = 30;
 %0A%0Afu
@@ -1666,32 +1666,47 @@
 on _logs(params,
+ backoff, tail,
  cb) %7B%0A%09return m
@@ -1817,16 +1817,17 @@
 %0A    if 
+(
 (result.
@@ -1835,16 +1835,25 @@
 ount %3E 0
+ %7C%7C tail)
  && !res
@@ -1873,90 +1873,690 @@
     
+if (
 result.
-line += 1;%0A      params.line = result.line;%0A      return _logs(params, cb);
+count %3E 0) %7B%0A        // store new last line in method params%0A        params.line = result.line;%0A        backoff = 0;%0A      %7D%0A      else if (backoff %3C MAX_BACKOFF_SECS) %7B%0A        // increase backoff geometrically%0A        if (backoff === 0) backoff = 1;%0A        else backoff *= 2;%0A      %7D%0A      else backoff = MAX_BACKOFF_SECS; // cap backoff at this%0A%0A      if (backoff %3E 0) %7B%0A        // sleep for backoff secs then query logs again%0A        return setTimeout(function _interval() %7B%0A          return _logs(params, backoff, tail, cb);%0A        %7D, backoff * 1000);%0A      %7D%0A      else %7B%0A        // querey logs immediately%0A        return _logs(params, backoff, tail, cb);%0A      %7D
 %0A   

enable jobs logs streaming while job is running, using tail option