import request from 'request';
import Q from 'q';

const EXECUTE_URL = 'http://agent.chainscript.io/execute';
const SNAPSHOTS_URL = 'https://chainscript.firebaseio.com/snapshots/';

export default class Chainscript {

  /**
   * Loads a script from an existing uuid
   *
   * @param {String} uuid The uuid of the script
   * @returns {Promise} A promise that resolves with a new Chainscript
   */
  static load = uuid => {
    const deferred = Q.defer();

    request.get(
      SNAPSHOTS_URL + 'chainscript-document-' + uuid + '.json',
      {json: true},
      (err, resp, body) => {
        if (err) {
          return deferred.reject(err);
        }

        if (resp.statusCode >= 400) {
          return deferred.reject(
            new Error('Unexpected status: ' + resp.statusCode)
          );
        }

        deferred.resolve(new Chainscript(body));
      }
    );

    return deferred.promise;
  };

  /**
   * Construct a new chainscript.
   *
   * @param {Object | string} [document={}] The initial script
   * @param {int} [numCommands={}] Private
   */
  constructor(script = {}, numCommands = 0) {
    // Clone the script for safety
    this.script = JSON.parse(JSON.stringify(script));
    this.numCommands = numCommands;
  }

  /**
   * Returns the script as JSON.
   *
   * @returns {Object} JSON representation of the script
   */
  toJSON() {
    // Clone the script for safety
    return JSON.parse(JSON.stringify(this.script));
  }

  /**
   * Clones the script.
   *
   * @returns {Chainscript} A clone of the script
   */
  clone() {
    return new Chainscript(this.script, this.numCommands);
  }

  /**
   * Run the script.
   *
   * @returns {Promise} A promise that resolves with a new Chainscript
   */
  run() {
    const deferred = Q.defer();

    request.post(
      EXECUTE_URL,
      {
        body: this.script,
        json: true
      },
      (err, resp, body) => {
        if (err) {
          return deferred.reject(err);
        }

        if (resp.statusCode >= 400) {
          return deferred.reject(
            new Error('Unexpected status: ' + resp.statusCode)
          );
        }

        deferred.resolve(new Chainscript(body));
      }
    );

    return deferred.promise;
  }

  addCommand(command) {
    const script = JSON.parse(JSON.stringify(this.script));
    const numCommands = this.numCommands;
    script.execute = script.execute || {};
    script.execute[numCommands] = command;

    return new Chainscript(script, numCommands + 1);
  }

  /**
   * Adds a snapshot command
   */
  snapshot() {
    return this.addCommand({snapshot: {}});
  }

  /**
   * Adds a notarize command
   */
  notarize() {
    return this.addCommand({notarize: {}});
  }

  /**
   * Adds a send email command
   */
  email(to) {
    return this.addCommand({send_email: {to}});
  }

}

@@ -1019,51 +1019,8 @@
 ipt%0A
-   * @param %7Bint%7D %5BnumCommands=%7B%7D%5D Private%0A
    *
@@ -1050,25 +1050,8 @@
 = %7B%7D
-, numCommands = 0
 ) %7B%0A
@@ -1162,28 +1162,210 @@
 mands = 
-numCommands;
+0;%0A%0A    if (typeof script.execute !== 'undefined') %7B%0A      for (const s in script.execute) %7B%0A        if (script.execute.hasOwnProperty(s)) %7B%0A          this.numCommands++;%0A        %7D%0A      %7D%0A    %7D
 %0A  %7D%0A%0A  
@@ -1719,26 +1719,8 @@
 ript
-, this.numCommands
 );%0A 
@@ -2419,49 +2419,8 @@
 ));%0A
-    const numCommands = this.numCommands;
 %0A   
@@ -2478,16 +2478,21 @@
 execute%5B
+this.
 numComma
@@ -2545,25 +2545,8 @@
 ript
-, numCommands + 1
 );%0A 

Remove numCommands from constructor