'use strict';

(({ App, esprima }) => {
  const { Syntax } = esprima;

  const INVALID_NODE_TYPES = [
    Syntax.CallExpression,
    Syntax.FunctionExpression,
    Syntax.FunctionDeclaration,
    Syntax.VariableDeclaration,
    Syntax.AssignmentExpression,
  ];

  const isGlobalVariableExpression = (node) => {
    if (
      node.type === Syntax.CallExpression &&
      node.callee.object &&
      node.callee.object.name === 'JSON' &&
      node.callee.property &&
      node.callee.property.name === 'parse'
    ) {
      let argument = node.arguments[0];

      if (argument && argument.type === Syntax.LogicalExpression) {
        argument = argument.left;

        if (argument && argument.type === Syntax.CallExpression && argument.callee.name === 'P') {
          argument = argument.arguments[0];

          if (argument && argument.type === Syntax.Literal && argument.value === 'basglobal') {
            return true;
          }
        }
      }
    }

    return false;
  };

  App.Inspector.utils.isValidExpression = (expression) => {
    try {
      let isValid = true;

      (function traverse(node) {
        if (INVALID_NODE_TYPES.includes(node.type)) {
          if (!isGlobalVariableExpression(node)) {
            isValid = false;
          }
        } else {
          for (let key in node) {
            if (node[key] && typeof node[key] === 'object') {
              traverse(node[key]);
            }
          }
        }
      })(esprima.parseScript(`(${expression})`));

      return isValid;
    } catch {
      return false;
    }
  };
})(window);
