/* Client-side part of StreamGoose */

/* escape HTML entities (for non-server-provided stuff) */
function esc(s) {
  return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
          .replace(/"/g,'&quot;').replace(/'/g,'&apos;')
}

/* handle Twitch, YouTube and Kick emotes */
function handleEmotes(text) {
  var twurl = 'https://static-cdn.jtvnw.net/emoticons/v2/$id/default/dark/1.0'
  var kickurl = 'https://files.kick.com/emotes/$id/fullsize'
  /* Handle Twitch emotes coming from backends */
  text = text.replace(/#TWEMOTE-[^\s]+#/g,
    a=>'<img src="' + twurl.replace('$id', a.split('-')[1].slice(0,-1)) + '">')
  /* Handle Kick emotes coming from backends */
  text = text.replace(/#KKEMOTE-[^\s]+#/g,
    a=>'<img src="' + kickurl.replace('$id', a.split('-')[1].slice(0,-1)) + '">')
  /* Handle YouTube emotes */
  text = text.replace(/:[^\s]+:/g, a => {
    if(YT_EMOTES.indexOf(a) > -1) /* found in the database */
      return '<img src="/img/yt-emotes/' + a + '.png">'
    else return a
  })
  return text
}

/* detect if there are any overridden styles */
function overrideStyles(text) {
  var styles = '', re
  if(messageHighlightRules) {
    for(re in messageHighlightRules) {
      if((new RegExp(re, 'iu')).test(text))
        styles += 'color:' + messageHighlightRules[re] + ';'
    }
  }
  if(styles.length > 0) styles = ' style="' + esc(styles) + '"'
  return styles
}

/* individual message appender */
function gooseAppendMessage(id, native_id, author_id, type, timestamp, username, text, icon) {
  var html = ""
  if(parseInt(id) > 0 && type.length > 0) {
    if(type == "delmsg") { /* message deletion event */
      var el = document.querySelector('[data-native-id="' + esc(native_id) + '"]')
      if(el) el.parentNode.removeChild(el)
    } else if(type == "deluser") { /* bulk deletion event by username */
      var els = document.querySelectorAll('[data-author-id="' + esc(author_id) + '"]')
      if(els && els.length > 0) {
        var i, l = els.length
        for(i=0;i<l;i++) els[i].parentNode.removeChild(els[i])
      }
    } else { /* message appending event */
      var classes = type.split('^'), cl = classes.length, j,
          colorpref = null, badges = [], platform, bname
      for(j=0;j<cl;j++) { /* detect color preference */
        if(classes[j].startsWith('color'))
          colorpref = classes[j].slice(5) /* remove color word */
        if(classes[j].startsWith('badge')) { /* remove the class but cache it */
          badges.push(classes[j].slice(5)) /* remove badge word */
          classes[j] = "" /* remove the class from the list */
        }
      }
      html += '<div data-msg-id="' + id + '" data-native-id="' + esc(native_id) + '" data-author-id="'
                + esc(author_id) + '" class="' + classes.join(' ') +'">'
      /* handle badges and icons */
      html += '<span class=icon>'
      for(j=0,cl=badges.length;j<cl;j++) { /* iterate over badges */
        platform = badges[j].slice(0,2) /* first 2 characters denote the platform */
        bname = badges[j].slice(2) /* the rest is the badge name itself */
        html += '<img class=badge src="/badge/{platform}/{badgename}">'
                .replace('{platform}', platform).replace('{badgename}', bname)
      }
      if(icon.length > 0) /* user icon, if present */
        html += '<img src="' + icon + '">'
      html += '</span>'
      html += '<span class=timestamp>' + timestamp + '</span>'
      html += '<span class=username'
      if(colorpref) html += ' style="color:' + colorpref + '"'
      html += '>' + username + '</span>'
      html += '<span class=msg' + overrideStyles(text) +'>' + handleEmotes(text) + '</span></div>'
      document.getElementById("msglist").innerHTML += html
    }
  }
  /* autoscroll to the end */
  window.setTimeout(function(){window.scrollTo(0, document.body.scrollHeight)}, 150)
}

/* entry point, set up an event source */
window.addEventListener('DOMContentLoaded', function() {
  var msgSource = new EventSource('/sse')
  msgSource.onmessage = e => {
    var msg = JSON.parse(e.data)
    gooseAppendMessage(msg.id, msg.native_id, msg.author_id, msg.type, msg.timestamp, msg.username, msg.text, msg.icon)
  }
}, false)
