'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.averageTransitionProbability = averageTransitionProbability;
exports.train = train;

exports.default = function (text) {
  return averageTransitionProbability(text, _model2.default.matrix) <= _model2.default.threshold;
};

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _fs = require('fs');

var _fs2 = _interopRequireDefault(_fs);

var _model = require('./model.json');

var _model2 = _interopRequireDefault(_model);

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

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

var encoding = 'utf8';
var defaultTrainingFileName = './data/big.txt';
var modelFileName = './lib/model.json';
var acceptedChars = 'abcdefghijklmnopqrstuvwxyz ';
var pos = _lodash2.default.fromPairs(acceptedChars.split('').map(function (char, i) {
  return [char, i];
}));

var normalize = function normalize(line) {
  var lowerCaseChars = _lodash2.default.map(line.split(''), _lodash2.default.toLower);
  return _lodash2.default.filter(lowerCaseChars, function (char) {
    return _lodash2.default.includes(acceptedChars, char);
  });
};

var ngram = function ngram(n, line, iteratee) {
  var filtered = normalize(line);
  for (var start = 0; start <= filtered.length - n; start++) {
    iteratee.apply(undefined, _toConsumableArray(filtered.slice(start, start + n)));
  }
};

var readLines = function readLines(fileName) {
  return _lodash2.default.compact(_fs2.default.readFileSync(fileName, encoding).split('\n'));
};

function averageTransitionProbability(line, probabilityMatrix) {
  var logaritmicProbability = 0;
  var transitionCount = 0;
  ngram(2, line, function (a, b) {
    logaritmicProbability += probabilityMatrix[pos[a]][pos[b]];
    transitionCount += 1;
  });
  return Math.exp(logaritmicProbability / (transitionCount || 1));
}

function train() {
  var trainingFileName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultTrainingFileName;

  var k = acceptedChars.length;
  var matrix = [].concat(_toConsumableArray(Array(k))).map(function () {
    return [].concat(_toConsumableArray(Array(k))).map(function () {
      return 10;
    });
  });

  var lines = readLines(trainingFileName);
  lines.forEach(function (line) {
    ngram(2, line, function (a, b) {
      matrix[pos[a]][pos[b]] += 1;
    });
  });

  matrix.forEach(function (row, i) {
    var rowSum = _lodash2.default.sum(row);
    _lodash2.default.range(row.length).forEach(function (j) {
      matrix[i][j] = Math.log(row[j] / rowSum);
    });
  });

  var good = _lodash2.default.map(readLines('./data/good.txt'), function (line) {
    return averageTransitionProbability(line, matrix);
  });
  var bad = _lodash2.default.map(readLines('./data/bad.txt'), function (line) {
    return averageTransitionProbability(line, matrix);
  });

  console.assert(_lodash2.default.min(good) > _lodash2.default.max(bad), 'Good Model');

  var threshold = (_lodash2.default.min(good) + _lodash2.default.max(bad)) / 2;

  var content = JSON.stringify({ matrix: matrix, threshold: threshold });
  _fs2.default.writeFileSync(modelFileName, content, encoding);
}