import { assign } from 'ember-platform';
import { moduleForComponent } from 'ember-qunit';
import { skip } from 'qunit';

moduleForComponent('chat/chat-line', 'Chat Line Component', {
  needs: [
    'component:message-line',
    'component:whisper-line'
  ],
  setup: function () {
    this.getComponent = function (args) {
      let defaultInfo = {
        color: '#FF7F50',
        from: 'Extalix',
        message: 'Public statement!',
        style: undefined,
        date: new Date(),
        labels: ['owner', 'mod', 'turbo', 'staff'],
        tags: { emotes: {} }
      };

      return this.subject({msgObject: assign(defaultInfo, args)});
    };

    this.getComponentWithArgs = function (msg, emotes, currentUser, from) {
      return this.subject({
        currentUserNick: currentUser || 'Extalix',
        msgObject: {
          message: msg,
          tags: {
            emotes: emotes
          },
          from: from
        }
      });
    };
  }
});

let _matchesTextToken = (text) => {
  return (assert, token) => {
    assert.ok(token.type === 'text');
    assert.ok(token.text === text);
  };
};

let _matchesEmoticonToken = (text) => {
  return (assert, token) => {
    assert.ok(token.type === 'emoticon');
    assert.ok(token.altText === text);
  };
};

let _matchesMentionToken = (text) => {
  return (assert, token) => {
    assert.ok(token.type === 'mention');
    assert.ok(token.user === text);
  };
};

let _matchesLinkToken = (text) => {
  return (assert, token) => {
    assert.ok(token.type === 'link');
    assert.ok(token.text === text);
  };
};

let _matchTokens = (assert, tokens, matchers) => {
  assert.ok(tokens.length === matchers.length);
  tokens.forEach((token, i) => {
    matchers[i](assert, token);
  });
};

skip('it works!', function (assert) {
  assert.ok(this.getComponent());
});

skip('can create whisper line by passing in msgobject with style whisper', function (assert) {
  this.getComponent({style: 'whisper'});
  assert.ok(this.$().find('.whisper-line'));
});

skip('if style is not whisper then message line is created', function (assert) {
  this.getComponent();
  assert.ok(this.$().find('.message-line'));
});

skip('text-only message tokenization works', function (assert) {
  let component = this.getComponentWithArgs('lol here is some pizza');
  _matchTokens(assert, component.get('tokenizedMessage'), [
    _matchesTextToken('lol here is some pizza')
  ]);
});

skip('link tokenization works ', function (assert) {
  let component = this.getComponentWithArgs('lol http://www.google.com');
  _matchTokens(assert, component.get('tokenizedMessage'), [
    _matchesTextToken('lol '),
    _matchesLinkToken('http://www.google.com')
  ]);
});

skip('emoticon tokenization works', function (assert) {
  let component = this.getComponentWithArgs('lol Kappa', {25: [4, 8]});
  _matchTokens(assert, component.get('tokenizedMessage'), [
    _matchesTextToken('lol '),
    _matchesEmoticonToken('Kappa')
  ]);
});

skip('sender mention tokenization works', function (assert) {
  let component = this.getComponentWithArgs('lol @Bowser I just saved Peach again', {}, 'Mario', 'Mario');
  _matchTokens(assert, component.get('tokenizedMessage'), [
    _matchesTextToken('lol '),
    _matchesMentionToken('@Bowser'),
    _matchesTextToken(' I just saved Peach again')
  ]);
});

skip('receiver mention tokenization works', function (assert) {
  let component = this.getComponentWithArgs('Curse you @Mario!', {}, 'Mario');
  _matchTokens(assert, component.get('tokenizedMessage'), [
    _matchesTextToken('Curse you '),
    _matchesMentionToken('@Mario'),
    _matchesTextToken('!')
  ]);
});

skip('complex tokenization works', function (assert) {
  let component = this.getComponentWithArgs('Thank you @Mario! <3 Visit www.mushroomkingdomcastle.com for your reward!', {1: [18, 19]}, 'Mario', 'Peach');
  _matchTokens(assert, component.get('tokenizedMessage'), [
    _matchesTextToken('Thank you '),
    _matchesMentionToken('@Mario'),
    _matchesTextToken('! '),
    _matchesEmoticonToken('<3'),
    _matchesTextToken(' Visit '),
    _matchesLinkToken('www.mushroomkingdomcastle.com'),
    _matchesTextToken(' for your reward!')
  ]);
});

skip('multiple emoticons tokenization works', function (assert) {
  let component = this.getComponentWithArgs('lol Kappa <3 Kappa', {25: [[4, 8], [13, 17]], 1: [10, 11]});
  _matchTokens(assert, component.get('tokenizedMessage'), [
    _matchesTextToken('lol '),
    _matchesEmoticonToken('Kappa'),
    _matchesTextToken(' '),
    _matchesEmoticonToken('<3'),
    _matchesTextToken(' '),
    _matchesEmoticonToken('Kappa')
  ]);
});

skip('links are preferred to emoticons', function (assert) {
  let component = this.getComponentWithArgs('lol www.Kappa.com', {25: [8, 12]});
  _matchTokens(assert, component.get('tokenizedMessage'), [
    _matchesTextToken('lol '),
    _matchesLinkToken('www.Kappa.com')
  ]);
});

skip('mentions are preferred to emoticons', function (assert) {
  let component = this.getComponentWithArgs('lol @TheKappaMan', {25: [8, 12]}, 'TheKappaMan', 'Extalix');
  _matchTokens(assert, component.get('tokenizedMessage'), [
    _matchesTextToken('lol '),
    _matchesMentionToken('@TheKappaMan')
  ]);
});

skip('script tags gets escaped properly', function (assert) {
  let component = this.getComponentWithArgs("<script>alert('skip')</script>", {});
  let token = component.get('tokenizedMessage')[0];
  assert.ok(token.escaped('text') === "&lt;script&gt;alert(&#x27;skip&#x27;)&lt;/script&gt;");
});

skip('url link tokens contain valid fields', function (assert) {
  let component = this.getComponentWithArgs("www.twitch.tv/link", {});
  let token = component.get('tokenizedMessage')[0];
  assert.ok(token.type === "link");
  assert.ok(token.length === "www.twitch.tv/link".length);
  assert.ok(token.isDeleted === false);
  assert.ok(token.isMailTo === false);
  assert.ok(token.text === "www.twitch.tv/link");
  assert.ok(token.link === "https://www.twitch.tv/link");
});

skip('url link containing parentheses is parsed properly', function(assert) {
  let message = "https://www.wikiwand.com/en/Hydra_(genus)#/Non-senescence";
  let component = this.getComponentWithArgs(message);
  let token = component.get('tokenizedMessage')[0];
  assert.ok(token.link === message);
});

skip('email link tokens contain valid fields', function (assert) {
  let component = this.getComponentWithArgs("someuser@twitch.tv", {});
  let token = component.get('tokenizedMessage')[0];
  assert.ok(token.type === "link");
  assert.ok(token.length === "someuser@twitch.tv".length);
  assert.ok(token.isDeleted === false);
  assert.ok(token.isMailTo === true);
  assert.ok(token.text === "someuser@twitch.tv");
  assert.ok(token.link === "someuser@twitch.tv");
});

skip('emoticon tokens contain valid fields', function (assert) {
  let component = this.getComponentWithArgs("Kappa", {25:[[0,4]]});
  let token = component.get('tokenizedMessage')[0];
  assert.ok(token.type === "emoticon");
  assert.ok(token.length === "Kappa".length);
  assert.ok(token.altText === "Kappa");
  assert.ok(token.imgSrc === "//static-cdn.jtvnw.net/emoticons/v1/25/1.0");
  assert.ok(token.srcSet === "//static-cdn.jtvnw.net/emoticons/v1/25/2.0 2x");
});

skip('sender mention tokens contain valid fields', function (assert) {
  let component = this.getComponentWithArgs("@Pizza", {}, "skipuser", "skipuser");
  let token = component.get('tokenizedMessage')[0];
  assert.ok(token.type === "mention");
  assert.ok(token.length === "@Pizza".length);
  assert.ok(token.isOwnMessage === true);
  assert.ok(token.user === "@Pizza");
});

skip('receiver mention tokens contain valid fields', function (assert) {
  let component = this.getComponentWithArgs("@Pizza", {}, "pizza", "skipuser");
  let token = component.get('tokenizedMessage')[0];
  assert.ok(token.type === "mention");
  assert.ok(token.length === "@Pizza".length);
  assert.ok(token.isOwnMessage === false);
  assert.ok(token.user === "@Pizza");
});

skip('text tokens contain valid fields', function (assert) {
  let component = this.getComponentWithArgs("Some message");
  let token = component.get('tokenizedMessage')[0];
  assert.ok(token.type === "text");
  assert.ok(token.length === "Some message".length);
  assert.ok(token.text === "Some message");
});
