export default class Subscription {
  constructor(store, api, channel) {
    this.store = store;
    this.api = api;
    this.channel = channel;

    this.channel.setOnChannelError(this.onChannelError.bind(this));
    this.firstRoundComplete = false;
  }

  start() {
    if (this.api.ship) {
      this.firstRound();
    } else {
      console.error('~~~ ERROR: Must set api.ship before operation ~~~');
    }
  }

  delete() {
    this.channel.delete();
  }

  onChannelError(err) {
    console.error('event source error: ', err);
    console.log('initiating new channel');
    this.firstRoundComplete = false;
    setTimeout(2000, () => {
      this.store.handleEvent({
        data: { clear : true }
      });

      this.start();
    });
  }

  subscribe(path, app) {
    this.api.bind(path, 'PUT', this.api.ship, app,
      this.handleEvent.bind(this),
      (err) => {
        console.log(err);
        this.subscribe(path, app);
      },
      () => {
        this.subscribe(path, app);
      });
  }

  firstRound() {
    this.subscribe('/sole/' + this.api.dojoId, 'dojo');
  }

  handleEvent(diff) {
    this.store.handleEvent(diff);
  }
}


export default class Subscription {
  constructor(store, api, channel) {
    this.store = store;
    this.api = api;
    this.channel = channel;

    this.channel.setOnChannelError(this.onChannelError.bind(this));
    this.firstRoundComplete = false;
  }

  start() {
    if (this.api.ship) {
      this.firstRound();
    } else {
      console.error('~~~ ERROR: Must set api.ship before operation ~~~');
    }
    this.setupSlog();
  }

  setupSlog() {
    const slog = new EventSource('/~/slog', { withCredentials: true });
    let available = false;

    slog.onopen = e => {
      console.log('slog: opened stream');
      available = true;
    }

    slog.onmessage = e => {
      this.handleEvent({ txt: e.data });
    }

    slog.onerror = e => {
      console.error('slog: eventsource error:', e);
      if (!available) {
        this.handleEvent({ txt:
          'landscape: no printf stream. bad connection or old binary.'
        });
      } else {
        window.setTimeout(() => {
          if (slog.readyState !== EventSource.CLOSED) return;
          console.log('slog: reconnecting...');
          this.setupSlog();
        }, 10000);
      }
    }
  }

  delete() {
    this.channel.delete();
  }

  onChannelError(err) {
    console.error('event source error: ', err);
    console.log('initiating new channel');
    this.firstRoundComplete = false;
    setTimeout(2000, () => {
      this.store.handleEvent({
        data: { clear : true }
      });

      this.start();
    });
  }

  subscribe(path, app) {
    this.api.bind(path, 'PUT', this.api.ship, app,
      this.handleEvent.bind(this),
      (err) => {
        console.log(err);
        this.subscribe(path, app);
      },
      () => {
        this.subscribe(path, app);
      });
  }

  firstRound() {
    this.subscribe('/sole/' + this.api.dojoId, 'dojo');
  }

  handleEvent(diff) {
    this.store.handleEvent(diff);
  }
}


connect to slog stream for printfs