"use strict";

const EventEmitter = require('events').EventEmitter;
const request = require('request');

const NOTIFICATIONS_ENDPOINT = 'api.github.com/notifications';

/**
 * It responsible for getting user's notifications and emitting data event with them.
 *
 * @extends {EventEmitter}
 */
class GitHubNotifications extends EventEmitter {
  /**
   * Creates new EventEmitter which will notify about new notifications on GitHub.
   *
   * @constructor
   * @param {String} username GitHub username
   * @param {String} token Personal access token of GitHub profile
   */
  constructor(username, token) {
    super();

    this._username = username;
    this._token = token;
    this._url = `https://${this._username}:${this._token}@${NOTIFICATIONS_ENDPOINT}`;
    this._headers = {'User-Agent': 'telegram-bot-github'};

    this._process();
  }

  /**
   * Triggers each time when got response from GitHub notifications endpoint.
   *
   * @param error
   * @param response
   * @param body
   * @private
   */
  _onNotificationsResponse(error, response, body) {
    if (error) return console.error(error);

    const interval = (Number(response.headers['x-poll-interval']) || 60) * 1000;

    if (response.statusCode === 304 || response.statusCode === 200) {
      this._headers['If-Modified-Since'] = response.headers.date;
    }

    if (response.statusCode === 200) {
      body.forEach(notification => {
        const subjectUrl = notification.subject.url;
        const headers = {'User-Agent': 'telegram-bot-github'};

        request(subjectUrl, {headers, json: true}, this._onSubjectResponse.bind(this));
      });
    }

    setTimeout(this._process.bind(this), interval);
  }

  /**
   * Triggers each time when got response from subject endpoint.
   *
   * @param error
   * @param response
   * @param body
   * @private
   */
  _onSubjectResponse(error, response, body) {
    if (error) return console.error(error);

    if (response.statusCode === 200) {
      this.emit('notification', body.html_url);
    }
  }

  /**
   * Makes a request to GitHub notifications endpoint.
   *
   * @private
   */
  _process() {
    request(this._url, {headers: this._headers, json: true}, this._onNotificationsResponse.bind(this));
  }
}

module.exports = GitHubNotifications;

@@ -162,16 +162,45 @@
 ions';%0A%0A
+const subscribedUsers = %7B%7D;%0A%0A
 /**%0A * I
@@ -624,24 +624,270 @@
 e, token) %7B%0A
+    if (subscribedUsers%5Busername%5D instanceof GitHubNotifications) %7B%0A      console.log(%60Found already subscribed listener for $%7Busername%7D%60);%0A      return subscribedUsers%5Busername%5D;%0A    %7D%0A%0A    console.log(%60Creating new listener for $%7Busername%7D%60);%0A%0A
     super();
@@ -1110,16 +1110,55 @@
 ocess();
+%0A%0A    subscribedUsers%5Busername%5D = this;
 %0A  %7D%0A%0A  
@@ -1831,24 +1831,106 @@
 -github'%7D;%0A%0A
+        console.log(%60Get new notification for $%7Bthis._username%7D: $%7BsubjectUrl%7D%60);%0A
         requ
@@ -2018,24 +2018,118 @@
  %7D);%0A    %7D%0A%0A
+    console.log(%60Queue next request for $%7Bthis._username%7D after $%7Binterval / 1000%7D seconds%60);%0A
     setTimeo
@@ -2600,16 +2600,16 @@
 e%0A   */%0A
-
   _proce
@@ -2611,24 +2611,124 @@
 process() %7B%0A
+    console.log(%60Checking for new notifications on GitHub for $%7Bthis._username%7D via $%7Bthis._url%7D%60);%0A
     request(

Implement caching of subscribers