/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @emails react-core
 */

'use strict';

module.exports = function(context) {
  function isInDEVBlock(node) {
    let done = false;
    while (!done) {
      let parent = node.parent;
      if (!parent) {
        return false;
      }
      if (
        parent.type === 'IfStatement' &&
        node === parent.consequent &&
        parent.test.type === 'Identifier' &&
        // This is intentionally strict so we can
        // see blocks of DEV-only code at once.
        parent.test.name === '__DEV__'
      ) {
        return true;
      }
      node = parent;
    }
  }

  function reportWrapInDEV(node) {
    context.report({
      node: node,
      message: `Wrap console.{{identifier}}() in an "if (__DEV__) {}" check`,
      data: {
        identifier: node.property.name,
      },
      fix: function(fixer) {
        return [
          fixer.insertTextBefore(node.parent, `if (__DEV__) {`),
          fixer.insertTextAfter(node.parent, '}'),
        ];
      },
    });
  }

  function reportUnexpectedConsole(node) {
    context.report({
      node: node,
      message: `Unexpected use of console`,
    });
  }

  return {
    meta: {
      fixable: 'code',
    },
    MemberExpression: function(node) {
      if (
        node.object.type === 'Identifier' &&
        node.object.name === 'console' &&
        node.property.type === 'Identifier'
      ) {
        switch (node.property.name) {
          case 'error':
          case 'warn': {
            if (!isInDEVBlock(node)) {
              reportWrapInDEV(node);
            }
            break;
          }
          default: {
            reportUnexpectedConsole(node);
            break;
          }
        }
      }
    },
  };
};
