"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _craftAi = require("craft-ai");

var _constants = require("./constants");

var _semver = _interopRequireDefault(require("semver"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { keys.push.apply(keys, Object.getOwnPropertySymbols(object)); } if (enumerableOnly) keys = keys.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { if (i % 2) { var source = arguments[i] != null ? arguments[i] : {}; ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(arguments[i])); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(arguments[i], key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _toArray(arr) { return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function createInterpreter(fullDt, outputProperty) {
  var version = _semver.default.major(fullDt._version);

  var dt = fullDt.trees[outputProperty];

  var findNodeRecursion = function findNodeRecursion(dtNodeParent) {
    var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];

    if (path.length > 0) {
      var _path = _toArray(path),
          childIndex = _path[0],
          pathTail = _path.slice(1);

      var _findNodeRecursion = findNodeRecursion(dtNodeParent.children[childIndex], pathTail),
          dtNode = _findNodeRecursion.dtNode,
          decisionRules = _findNodeRecursion.decisionRules;

      if (dtNodeParent.decision_rule) {
        var _dtNodeParent$decisio = dtNodeParent.decision_rule,
            property = _dtNodeParent$decisio.property,
            operator = _dtNodeParent$decisio.operator,
            operand = _dtNodeParent$decisio.operand;
        return {
          dtNode: dtNode,
          decisionRules: _objectSpread({}, decisionRules, _defineProperty({}, property, [{
            operator: operator,
            operand: operand
          }].concat(_toConsumableArray(decisionRules[property] || []))))
        };
      } else {
        return {
          dtNode: dtNode,
          decisionRules: decisionRules
        };
      }
    } else {
      if (dtNodeParent.decision_rule) {
        var _dtNodeParent$decisio2 = dtNodeParent.decision_rule,
            _property = _dtNodeParent$decisio2.property,
            _operator = _dtNodeParent$decisio2.operator,
            _operand = _dtNodeParent$decisio2.operand;
        return {
          dtNode: dtNodeParent,
          decisionRules: _defineProperty({}, _property, [{
            operator: _operator,
            operand: _operand
          }])
        };
      } else {
        return {
          dtNode: dtNodeParent,
          decisionRules: []
        };
      }
    }
  };

  var findNode = function findNode(path) {
    // making the root node an exception
    if (path == '0') {
      return {
        dtNode: dt,
        decisionRules: {}
      };
    } else {
      var _path$split$map = path.split(_constants.NODE_PATH_SEPARATOR).map(function (n) {
        return parseInt(n);
      }),
          _path$split$map2 = _toArray(_path$split$map),
          pathTail = _path$split$map2.slice(1); // remove the first element of the path because it is the root path;


      return findNodeRecursion(dt, pathTail);
    }
  };

  if (version == 1) {
    return _objectSpread({
      version: version,
      outputProperty: outputProperty,
      dt: dt
    }, _craftAi.interpreter, {
      isLeaf: function isLeaf(dtNode) {
        return dtNode.predicted_value != null;
      },
      getPrediction: function getPrediction(dtNode) {
        return {
          confidence: dtNode.confidence,
          value: dtNode.predicted_value,
          distribution: {
            standard_deviation: dtNode.standard_deviation
          }
        };
      },
      findNode: findNode
    });
  } else {
    return _objectSpread({
      version: version,
      outputProperty: outputProperty,
      dt: dt
    }, _craftAi.interpreter, {
      isLeaf: function isLeaf(dtNode) {
        return dtNode.prediction != null;
      },
      getPrediction: function getPrediction(dtNode) {
        if (dtNode.prediction) {
          return dtNode.prediction;
        } else {
          var _interpreter$distribu = _craftAi.interpreter.distribution(dtNode),
              value = _interpreter$distribu.value,
              distribution = _objectWithoutProperties(_interpreter$distribu, ["value"]);

          if (typeof value === 'number') {
            return {
              value: value,
              confidence: undefined,
              distribution: distribution
            };
          } else {
            var majClass = value.map(function (p, i) {
              return {
                value: dt.output_values[i],
                p: p
              };
            }).reduce(function (majClass, _ref) {
              var value = _ref.value,
                  p = _ref.p;
              return p > majClass.p ? {
                value: value,
                p: p
              } : majClass;
            }, {
              p: 0
            });
            return {
              value: majClass.value,
              confidence: undefined,
              distribution: distribution
            };
          }
        }
      },
      findNode: findNode
    });
  }
}

var _default = createInterpreter;
exports.default = _default;