text: "use strict";
  
  let debug = require('debug')('pluginApi');
  let http = require('http');
  
  function inRangeOk(statusCode) {
      return statusCode >= 200 && statusCode < 300;
  }
  
  class SimplifierApi {
  
      /**
       * Create API object
       * @param {PluginSettings} settings plugin settings
       * @param {PluginDescription} description plugin description
       * @param {object} manifest plugin manifest
       */
      constructor(settings, description, manifest) {
          this.settings = settings;
          this.description = description;
          this.manifest = manifest;
          this.baseUrl = `http://${settings.registrationHost}:${settings.registrationPort}`;
      }
  
      register() {
          debug(`Registering plugin to Simplifier (located at ${this.baseUrl})`);
          return this._post('/api/registration', this.manifest).then(
              () => {
                  debug('Register successful');
              },
              (error) => {
                  debug(`Register error ${error.statusCode}: ${error.message}`);
                  throw 'Error Registering';
              }
          );
      }
  
      unregister() {
          debug('Unregistering from Simplifier ...');
          return this._delete(`/api/registration/${this.description.name}`).then(
              () => {
                  debug('Unregistering successful');
              },
              (error) => {
                  debug(`Unregister error ${error.statusCode}: ${error.message}`);
                  throw 'Error unregistering';
              }
          );
      }
  
      /**
       * Build headers for plugin API request.
       * @param {number?} userId options user id
       * @param {object} extendedHeaders addition headers
       * @returns {object} headers object
       * @private
       */
      _apiHeaders(userId, extendedHeaders) {
          let headers = {
              'Plugin-Secret': this.settings.registrationSecret,
              'Plugin-Request-Source': `Plugin ${this.description.name}`
          };
          if (userId) {
              headers['Simplifier-User'] = userId;
          }
  
          return Object.assign({}, headers, extendedHeaders || {});
      }
  
      _delete(url, userId) {
          return this._req(url, 'DELETE', userId);
      }
  
      _post(url, body, userId) {
          return this._reqWithBody(url, 'POST', body, userId);
      }
  
      /**
       * Run request against Simplifier API with JSON body.
       * @param {string} url url on Simplifier API
       * @param {string} method method to execute
       * @param {string|object} body json body to send
       * @param {number?} userId option userId
       * @returns {Promise} promise of response
       * @private
       */
      _reqWithBody(url, method, body, userId) {
          return new Promise((resolve, reject) => {
              let bodyStr = body;
              if (typeof body !== 'string')  {
                  bodyStr = JSON.stringify(body);
              }
              let jsonHeaders = {
                  'Content-Type': 'application/json; charset=UTF-8',
                  'Content-Length': Buffer.byteLength(bodyStr)
              };
              let req = http.request({
                  hostname: this.settings.registrationHost,
                  port: this.settings.registrationPort,
                  path: url,
                  method: method,
                  headers: this._apiHeaders(userId, jsonHeaders)
              }, (res) => {
                  SimplifierApi._handleJsonResponse(res, resolve, reject);
              });
              req.write(bodyStr);
              req.end();
          });
      }
  
      /**
       * Run request against Simplifier API without body.
       * @param {string} url url on Simplifier API
       * @param {string} method method to execute
       * @param {number?} userId option userId
       * @returns {Promise} promise of response
       * @private
       */
      _req(url, method, userId) {
          return new Promise((resolve, reject) => {
              let req = http.request({
                  hostname: this.settings.registrationHost,
                  port: this.settings.registrationPort,
                  path: url,
                  method: method,
                  headers: this._apiHeaders(userId)
              }, (res) => {
                  SimplifierApi._handleJsonResponse(res, resolve, reject);
              });
              req.end();
          });
      }
  
      static _handleJsonResponse(res, resolve, reject) {
          let streamedData = '';
          res.on('data', (data) => streamedData += data);
          res.on('end', () => {
              if (inRangeOk(res.statusCode)) {
                  let responseJson = streamedData;
                  try {
                      responseJson = JSON.parse(streamedData);
                  } catch(e) {
                  }
                  resolve(responseJson);
              } else {
                  let message = streamedData;
                  try {
                      message = JSON.parse(streamedData)['message']
                  } catch (e) {}
                  reject({'message': message, 'statusCode': res.statusCode});
              }
          });
      }
  
  }
  
  module.exports = new SimplifierApi(
      require('./settings'),
      require('./pluginDescription'),
      require('./pluginManifest')
  );