const passiveEventListenerNames = new Set(['touchstart', 'touchmove', 'wheel', 'mousewheel'])

const propIsPassiveTrue = prop => prop.key && prop.key.name === 'passive' && prop.value && prop.value.value === true

module.exports = {
  meta: {
    docs: {},
    fixable: 'code'
  },

  create(context) {
    return {
      ['CallExpression[callee.property.name="addEventListener"]']: function(node) {
        const [name, listener, options] = node.arguments
        if (name.type !== 'Literal') return
        if (passiveEventListenerNames.has(name.value)) return
        if (options && options.type === 'ObjectExpression') {
          const i = options.properties.findIndex(propIsPassiveTrue)
          if (i === -1) return
          const passiveProp = options.properties[i]
          const l = options.properties.length
          const source = context.getSourceCode()
          context.report({
            node: passiveProp,
            message: `"${name.value}" event listener is not cancellable and so \`passive: true\` does nothing.`,
            fix(fixer) {
              const removals = []
              if (l === 1) {
                removals.push(options)
                removals.push(...source.getTokensBetween(listener, options))
              } else {
                removals.push(passiveProp)
                if (i > 0) {
                  removals.push(...source.getTokensBetween(options.properties[i - 1], passiveProp))
                } else {
                  removals.push(...source.getTokensBetween(passiveProp, options.properties[i + 1]))
                }
              }
              return removals.map(t => fixer.remove(t))
            }
          })
        }
      }
    }
  }
}