document.addEventListener('DOMContentLoaded', () => {
  function humanFileSize(bytes) {
      const thresh = 1024
      if(Math.abs(bytes) < thresh) {
          return bytes + ' B'
      }
      const units = ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB']
      var u = -1
      do {
          bytes /= thresh
          ++u
      } while(Math.abs(bytes) >= thresh && u < units.length - 1)
      return bytes.toFixed(1)+' '+units[u]
  }


  function textToA(line) {
    let outerElement = document.createElement('div')
    outerElement.innerHTML = line
    return outerElement.getElementsByTagName('a')[0]
  }

  function parseLine(line) {
    const href = textToA(line).href
    const filename = href.substr(-1) === '/' ? decodeURIComponent(href.split('/').slice(-2, -1)[0]) : decodeURIComponent(href.split('/').pop())
    const size = line.split(' ').pop()
    return {
      href: href,
      filename: filename,
      size: size
    }
  }

  function processLine(line) {
    meta = parseLine(line)
    return `<tr><td><a href="${meta.href}">${meta.filename}</a></td><td>${meta.size === '-' ? '-' : humanFileSize(meta.size)}</td></tr>`
  }

  function addZebraStripes(rows) {
    // this should be done in CSS, but AFAIU it does not support limiting
    // :nth-child to elements matching a previous :not selector
    rows.forEach((row, idx) => {
      if (idx % 2 === 0) {
        row.classList.add("zebra-stripe")
      } else {
        row.classList.remove("zebra-stripe")
      }
    })
  }

  const collator = new Intl.Collator('kn', {numeric: true})

  // transform plain text to table
  document.querySelector('pre').outerHTML = '<table><thead><tr><th>Name</th><th>Size</th></tr></thead><tbody><tr><td><a href="..">..</a></td><td>-</td></tr>' + document.querySelector('pre').innerHTML
    .split('\n')
    .filter(line => line !== '')
    .filter(line => line !== '<a href="../">../</a>')
    .map(processLine)
    .sort(collator.compare)
    .join('\n') + '</tbody></table>'

  let searchField = document.createElement('input')
  searchField.id = 'search-field'
  searchField.autofocus = true
  document.querySelector('body').insertBefore(searchField, document.querySelector('table'))

  const rows = Array.from(document.querySelectorAll('tbody tr'))

  addZebraStripes(rows)

  document.querySelector('#search-field').addEventListener("input", e => {
    const searchValue = e.target.value.toLowerCase()
    rows.forEach(row => {
      const file = row.querySelector('td:nth-child(1) a').innerText
      if (!file.toLowerCase().includes(searchValue)) {
        row.classList.add("hidden")
      } else {
        row.classList.remove("hidden")
      }
    })

    const visibleRows = rows.filter(row => !row.classList.contains("hidden"))
    if (visibleRows.length === 1) {
      const target = visibleRows[0].querySelector('td a').href
      if (target.substr(-1) === '/') {
        window.location = target
      }
    }
    addZebraStripes(visibleRows)
  })
})