const { CompositeDisposable, File, Directory, Emitter } = require('atom')
const path = require('path')

module.exports = class Watcher {
  constructor () {
    this.destroy = this.destroy.bind(this)
    this.emitter = new Emitter()
    this.disposables = new CompositeDisposable()
    this.entities = [] // Used for specs
  }

  onDidDestroy (callback) {
    this.emitter.on('did-destroy', callback)
  }

  onDidChangeGlobals (callback) {
    this.emitter.on('did-change-globals', callback)
  }

  destroy () {
    this.disposables.dispose()
    this.entities = null
    this.emitter.emit('did-destroy')
    this.emitter.dispose()
  }

  watch () {
    // override me
  }

  loadStylesheet (stylesheetPath) {
    // override me
  }

  loadAllStylesheets () {
    // override me
  }

  emitGlobalsChanged () {
    this.emitter.emit('did-change-globals')
  }

  watchDirectory (directoryPath) {
    if (this.isInAsarArchive(directoryPath)) return
    const entity = new Directory(directoryPath)
    this.disposables.add(entity.onDidChange(() => this.loadAllStylesheets()))
    this.entities.push(entity)
  }

  watchGlobalFile (filePath) {
    const entity = new File(filePath)
    this.disposables.add(entity.onDidChange(() => this.emitGlobalsChanged()))
    this.entities.push(entity)
  }

  watchFile (filePath) {
    if (this.isInAsarArchive(filePath)) return
    const reloadFn = () => this.loadStylesheet(entity.getPath())

    const entity = new File(filePath)
    this.disposables.add(entity.onDidChange(reloadFn))
    this.disposables.add(entity.onDidDelete(reloadFn))
    this.disposables.add(entity.onDidRename(reloadFn))
    this.entities.push(entity)
  }

  isInAsarArchive (pathToCheck) {
    const { resourcePath } = atom.getLoadSettings()
    return (
      pathToCheck.startsWith(`${resourcePath}${path.sep}`) &&
      path.extname(resourcePath) === '.asar'
    )
  }
}
