export default class Updater {
  constructor (options) {
    this.oldScript = [] // 存储初始的 script 哈希信息
    this.newScript = [] // 存储新的 script 哈希信息
    this.dispatch = {} // 一个小型的发布/订阅系统，用于通知用户更新
    this.interval = null
    this.init() // 初始化
    this.timing(options?.timer) // 轮询
  }

  async init () {
    const html = await this.getHtml()
    this.oldScript = this.parserScript(html)
  }

  async getHtml () {
    const html = await fetch('/').then(res => res.text()) // 获取 index.html
    return html
  }

  parserScript (html) {
    const reg = new RegExp(/<script(?:\s+[^>]*)?>(.*?)<\/script\s*>/ig) // 匹配 script 标签的正则表达式
    return html.match(reg) // 匹配 script 标签
  }

  // 发布/订阅通知
  on (key, fn) {
    (this.dispatch[key] || (this.dispatch[key] = [])).push(fn)
    return this
  }

  compare (oldArr, newArr) {
    const base = oldArr.length
    const arr = Array.from(new Set(oldArr.concat(newArr)))
    // 如果新旧数组长度相同，则表示没有更新
    if (arr.length === base) {
      this.dispatch['no-update'].forEach(fn => {
        fn()
      })
    } else {
      // 否则通知有更新
      this.dispatch['update'].forEach(fn => {
        fn()
      })
    }
  }

  timing (time = 10000) {
    // 轮询
    this.interval = setInterval(async () => {
      const newHtml = await this.getHtml()
      this.newScript = this.parserScript(newHtml)
      this.compare(this.oldScript, this.newScript)
    }, time)
  }

  start () {
  }
  stop () {
    clearInterval(this.interval)
  }
}
