'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var React = require('react');
var PropTypes = require('prop-types');
var _ = require('lodash');
var ValidationAction = require('../../actions');
var bootstrap = require('react-bootstrap');
var FormGroup = bootstrap.FormGroup;
var FormControl = bootstrap.FormControl;
var DropdownButton = bootstrap.DropdownButton;
var MenuItem = bootstrap.MenuItem;

// const debug = require('debug')('mongodb-compass:validation');

var CASE_INSENSITIVE = 'case insensitivity';
var MULTILINE = 'multiline anchor match';
var EXTENDED = 'extended ignore non-escaped whitespace';
var NEWLINE = 'dot * includes newline';

var RuleCategoryRegex = function (_React$Component) {
  _inherits(RuleCategoryRegex, _React$Component);

  function RuleCategoryRegex(props) {
    _classCallCheck(this, RuleCategoryRegex);

    var _this = _possibleConstructorReturn(this, (RuleCategoryRegex.__proto__ || Object.getPrototypeOf(RuleCategoryRegex)).call(this, props));

    _this.state = {
      value: _.get(_this.props.parameters, 'regex', ''),
      options: _.get(_this.props.parameters, 'options', '')
    };
    return _this;
  }

  _createClass(RuleCategoryRegex, [{
    key: 'componentWillReceiveProps',
    value: function componentWillReceiveProps(nextProps) {
      this.setState({
        value: _.get(nextProps.parameters, 'regex', ''),
        options: _.get(nextProps.parameters, 'options', '')
      });
    }
  }, {
    key: 'onChange',
    value: function onChange(evt) {
      this.setState({
        value: evt.target.value
      });
    }
  }, {
    key: 'onOptionChange',
    value: function onOptionChange(evt) {
      if (evt.target.checked) {
        // Add the option to the Regex options.
        this.setState({ options: '' + this.state.options + evt.target.value });
      } else {
        // Remove the option from the Regex options.
        this.setState({ options: this.state.options.replace(evt.target.value, '') });
      }
    }
  }, {
    key: 'onDropdownClosed',
    value: function onDropdownClosed() {
      this.onBlur();
    }
  }, {
    key: 'onBlur',
    value: function onBlur() {
      ValidationAction.setRuleParameters(this.props.id, {
        regex: this.state.value,
        options: this.state.options
      });
    }

    /**
     * get the initial parameters for this rule category.
     *
     * @return {Object}   the parameters for this rule.
     */

  }, {
    key: 'isOptionSelected',
    value: function isOptionSelected(option) {
      return this.state.options.indexOf(option) > -1;
    }

    /**
     * Render ValidationHeader.
     *
     * @returns {React.Component} The view component.
     */

  }, {
    key: 'render',
    value: function render() {
      var controlId = 'param-regex-' + this.props.id;
      return React.createElement(
        FormGroup,
        { controlId: controlId },
        React.createElement(FormControl, {
          type: 'text',
          value: this.state.value,
          placeholder: 'Enter regular expression',
          onChange: this.onChange.bind(this),
          onBlur: this.onBlur.bind(this),
          disabled: !this.props.isWritable
        }),
        React.createElement(
          DropdownButton,
          { id: 'regex-options',
            title: 'Options',
            className: 'regex-dropdown',
            onClose: this.onDropdownClosed.bind(this)
          },
          React.createElement(
            MenuItem,
            { header: true },
            React.createElement('input', {
              type: 'checkbox',
              value: 'i',
              checked: this.isOptionSelected('i'),
              disabled: !this.props.isWritable,
              onChange: this.onOptionChange.bind(this) }),
            React.createElement(
              'b',
              null,
              'i'
            ),
            CASE_INSENSITIVE
          ),
          React.createElement(
            MenuItem,
            { header: true },
            React.createElement('input', {
              type: 'checkbox',
              value: 'm',
              checked: this.isOptionSelected('m'),
              disabled: !this.props.isWritable,
              onChange: this.onOptionChange.bind(this) }),
            React.createElement(
              'b',
              null,
              'm'
            ),
            MULTILINE
          ),
          React.createElement(
            MenuItem,
            { header: true },
            React.createElement('input', {
              type: 'checkbox',
              value: 'x',
              checked: this.isOptionSelected('x'),
              disabled: !this.props.isWritable,
              onChange: this.onOptionChange.bind(this) }),
            React.createElement(
              'b',
              null,
              'x'
            ),
            EXTENDED
          ),
          React.createElement(
            MenuItem,
            { header: true },
            React.createElement('input', {
              type: 'checkbox',
              value: 's',
              checked: this.isOptionSelected('s'),
              disabled: !this.props.isWritable,
              onChange: this.onOptionChange.bind(this) }),
            React.createElement(
              'b',
              null,
              's'
            ),
            NEWLINE
          )
        )
      );
    }
  }], [{
    key: 'getInitialParameters',
    value: function getInitialParameters() {
      return {
        regex: '',
        options: ''
      };
    }

    /**
     * Convert the parameters describing the state of this rule to a query
     * value that MongoDB understands.
     *
     * @param {Object} params   the parameters describing the state of this rule
     *
     * @return {Object}   the value describing this rule.
     */

  }, {
    key: 'paramsToQuery',
    value: function paramsToQuery(params) {
      if (_.has(params, 'regex')) {
        return {
          $regex: _.get(params, 'regex', ''),
          $options: _.get(params, 'options', '')
        };
      }
      return false;
    }

    /**
     * Detect if a query can be represented by this rule, and if it can,
     * convert the a query value returned from the server to an object of
     * parameters describing the state of this rule.
     *
     * @param {Object} query   The query value for this field.
     *
     * @return {Object|Boolean}  the parameters describing the state of this rule
     *                           or false if the query cannot be described by
     *                           this rule.
     */

  }, {
    key: 'queryToParams',
    value: function queryToParams(query) {
      // $regex form
      if (_.includes(_.keys(query), '$regex')) {
        return {
          regex: query.$regex || '',
          options: query.$options || ''
        };
      }
      // javascript RegExp form
      if (_.isRegExp(query)) {
        return {
          regex: query.source,
          options: query.flags
        };
      }
      return false;
    }
  }]);

  return RuleCategoryRegex;
}(React.Component);

RuleCategoryRegex.propTypes = {
  id: PropTypes.string.isRequired,
  parameters: PropTypes.object.isRequired,
  isWritable: PropTypes.bool.isRequired
};

RuleCategoryRegex.displayName = 'RuleCategoryRegex';

module.exports = RuleCategoryRegex;