const {remote} = require('electron')

const SETTING = 'core.uriHandlerRegistration'
const PROMPT = 'prompt'
const ALWAYS = 'always'
const NEVER = 'never'

module.exports =
class ProtocolHandlerInstaller {
  isSupported () {
    return ['win32', 'darwin'].includes(process.platform)
  }

  isDefaultProtocolClient () {
    return remote.app.isDefaultProtocolClient('atom', process.execPath, ['--uri-handler', '--'])
  }

  setAsDefaultProtocolClient () {
    // This Electron API is only available on Windows and macOS. There might be some
    // hacks to make it work on Linux; see https://github.com/electron/electron/issues/6440
    return this.isSupported() && remote.app.setAsDefaultProtocolClient('atom', process.execPath, ['--uri-handler', '--'])
  }

  initialize (config, notifications) {
    if (!this.isSupported()) {
      return
    }

    const behaviorWhenNotProtocolClient = config.get(SETTING)
    switch (behaviorWhenNotProtocolClient) {
      case PROMPT:
        if (!this.isDefaultProtocolClient()) {
          this.promptToBecomeProtocolClient(config, notifications)
        }
        break
      case ALWAYS:
        if (!this.isDefaultProtocolClient()) {
          this.setAsDefaultProtocolClient()
        }
        break
      case NEVER:
        if (process.platform === 'win32') {
          // Only win32 supports deregistration
          const Registry = require('winreg')
          const commandKey = new Registry({hive: 'HKCR', key: `\\atom`})
          commandKey.destroy((_err, _val) => { /* no op */ })
        }
        break
      default:
        // Do nothing
    }
  }

  promptToBecomeProtocolClient (config, notifications) {
    let notification

    const withSetting = (value, fn) => {
      return function () {
        config.set(SETTING, value)
        fn()
      }
    }

    const accept = () => {
      notification.dismiss()
      this.setAsDefaultProtocolClient()
    }
    const decline = () => {
      notification.dismiss()
    }

    notification = notifications.addInfo('Register as default atom:// URI handler?', {
      dismissable: true,
      icon: 'link',
      description: 'Atom is not currently set as the default handler for atom:// URIs. Would you like Atom to handle ' +
        'atom:// URIs?',
      buttons: [
        {
          text: 'Yes',
          className: 'btn btn-info btn-primary',
          onDidClick: accept
        },
        {
          text: 'Yes, Always',
          className: 'btn btn-info',
          onDidClick: withSetting(ALWAYS, accept)
        },
        {
          text: 'No',
          className: 'btn btn-info',
          onDidClick: decline
        },
        {
          text: 'No, Never',
          className: 'btn btn-info',
          onDidClick: withSetting(NEVER, decline)
        }
      ]
    })
  }
}
