import { decode, toRGBA8 } from 'upng-js'
import _ from 'lodash'

class TileCache {
  constructor (options) {
    this.tiles = []
    this._loadTileImage = options.loadTileImage
    this.MAX_SIZE = options.maxCacheSize
  }

  addTile (tileCoord, options) {
    let { user_id, project_id, task_id, data_type } = options
    let tile = {
      loaded: false,
      user_id,
      project_id,
      task_id,
      data_type,
      tileCoord
    }
    tile.tileData = this._loadTileData(tile, options)
    this.tiles.push(tile)
    return tile
  }

  async _loadTileData (tile) {
    let { user_id, project_id, task_id, data_type, tileCoord } = tile
    let originalTile = null
    try {
      originalTile = await this._loadTileImage(user_id, project_id, task_id, data_type, tileCoord)
    } catch (err) {
      console.error(err)
      originalTile = null
    }
    if (!originalTile) {
      tile.loaded = true
      tile.lastVisited = new Date()
      tile.tileData = null
      return tile
    }
    const img = decode(originalTile)
    const rgba = new Uint8Array(toRGBA8(img)[0])
    tile.loaded = true
    tile.lastVisited = new Date()
    tile.tileData = rgba

    if (this.tiles.length > this.MAX_SIZE) {
      this.removeTile()
    }
    return tile
  }

  getTile (tileCoord, options) {
    let { user_id, task_id, data_type } = options
    for (let tile of this.tiles) {
      if (
        tile.user_id === user_id &&
        tile.task_id === task_id &&
        tile.data_type === data_type &&
        _.isEqual(tile.tileCoord, tileCoord)
      ) {
        tile.lastVisited = new Date()
        return tile
      }
    }
    return null
  }

  removeTile () {
    // 删除离上次访问时间最长的那个瓦片
    let tileIndex = -1,
      tile = null
    for (let i = 0; i < this.tiles.length; i++) {
      if (tile && tile.lastVisited > this.tiles[i].lastVisited) {
        continue
      }
      tileIndex = i
      tile = this.tiles[i]
    }
    this.tiles.splice(tileIndex, 1)
  }

  clear () {
    this.tiles = []
  }
}

export default TileCache
