import {
  combinePixies,
  filterPixie,
  stopUpdates,

} from 'redux-pixies'
import { close, update } from 'yaob'


import { makePeriodicTask } from '../../util/periodic-task'
import { shuffle } from '../../util/shuffle'

import { makeContextApi } from './context-api'
import {
  asInfoCacheFile,
  INFO_CACHE_FILE_NAME,
  infoCacheFile
} from './info-cache-file'





export const context = combinePixies({
  api(ai) {
    return {
      destroy() {
        close(ai.props.output.context.api)
      },
      update() {
        ai.onOutput(makeContextApi(ai))
        return stopUpdates
      }
    }
  },

  watcher(ai) {
    let lastLocalUsers
    let lastPaused
    let lastLogSettings

    return () => {
      if (
        lastLocalUsers !== ai.props.state.login.localUsers ||
        lastPaused !== ai.props.state.paused ||
        lastLogSettings !== ai.props.state.logSettings
      ) {
        lastLocalUsers = ai.props.state.login.localUsers
        lastPaused = ai.props.state.paused
        lastLogSettings = ai.props.state.logSettings
        if (ai.props.output.context.api != null) {
          update(ai.props.output.context.api)
        }
      }
    }
  },

  infoFetcher: filterPixie(
    (input) => {
      async function doInfoSync() {
        const { dispatch, io } = input.props

        const [infoServerUri] = shuffle(input.props.state.infoServers)
        const response = await fetch(`${infoServerUri}/v1/coreRollup`, {
          headers: { accept: 'application/json' }
        })
        if (!response.ok) return
        const json = await response.json()

        const infoCache = asInfoCacheFile(json)
        dispatch({
          type: 'INFO_CACHE_FETCHED',
          payload: infoCache
        })
        await infoCacheFile.save(io.disklet, INFO_CACHE_FILE_NAME, infoCache)
      }

      const infoTask = makePeriodicTask(doInfoSync, 10 * 60 * 1000, {
        onError(error) {
          input.props.onError(error)
        }
      })

      return {
        update() {
          if (!infoTask.started) infoTask.start()
        },
        destroy() {
          infoTask.stop()
        }
      }
    },
    props => (props.state.paused ? undefined : props)
  )
})
