"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

function _bluebird() {
  const data = require("bluebird");

  _bluebird = function () {
    return data;
  };

  return data;
}

function _stream() {
  const data = require("stream");

  _stream = function () {
    return data;
  };

  return data;
}

function _porterStemmer() {
  const data = require("porter-stemmer");

  _porterStemmer = function () {
    return data;
  };

  return data;
}

function _serverlessIndex() {
  const data = _interopRequireDefault(require("./serverless-index"));

  _serverlessIndex = function () {
    return data;
  };

  return data;
}

function _logger() {
  const data = _interopRequireDefault(require("../logger/logger"));

  _logger = function () {
    return data;
  };

  return data;
}

const stem = sentence => sentence.split(' ').map(_porterStemmer().stemmer).join(' ');

let indexInstance;

function tokenizeStr(str) {
  return str.trim().split(/(?=[A-Z])/).join(' ').toLowerCase().split(/ |_|-/).join(' ');
}
/**
 * returns the first sentence of the description.
 * @param {string} desc
 * @return {string}
 */


function minimizeDescription(desc = '') {
  return desc.split(/\.|;/)[0]; // split by a dot or a semicolon
}

function prepareDoc(docs, component) {
  const name = component.name;
  const tokenizedName = tokenizeStr(name);
  const functionNames = docs.map(doc => doc.name).join(' ');
  const minDescription = docs.map(doc => minimizeDescription(doc.description)).join(' ');
  return {
    id: name,
    name,
    tokenizedName,
    stemmedName: stem(tokenizedName),
    functionNames,
    tokenizedFunctionNames: tokenizeStr(functionNames),
    description: docs.map(doc => doc.description).join(' '),
    minDescription,
    stemmedMinDescription: stem(minDescription)
  };
}

function addAllToLocalIndex(components) {
  return new Promise(resolve => {
    const docs = components.map(component => prepareDoc(component.docs, component));
    const docStream = new (_stream().Readable)({
      objectMode: true
    }); // $FlowFixMe: a flow bug. Stream can be an object as well when objectMode is true

    docs.map(doc => docStream.push(doc));
    docStream.push(null);
    docStream.pipe(indexInstance.defaultPipeline()).pipe(indexInstance.add()).on('finish', () => {
      resolve('The indexing has been completed');
    });
  });
}

function addToLocalIndex(component) {
  return new Promise(resolve => {
    const doc = prepareDoc(component.docs, component);
    const docStream = new (_stream().Readable)({
      objectMode: true
    }); // $FlowFixMe: a flow bug. Stream can be an object as well when objectMode is true

    docStream.push(doc);
    docStream.push(null);
    docStream.pipe(indexInstance.defaultPipeline()).pipe(indexInstance.add()).on('finish', () => {
      resolve(component);
    });
  });
}

function index(_x, _x2) {
  return _index.apply(this, arguments);
}

function _index() {
  _index = (0, _bluebird().coroutine)(function* (component, scopePath) {
    // if (isWin) return Promise.resolve(component);
    try {
      indexInstance = yield _serverlessIndex().default.initializeIndex(scopePath);
      return addToLocalIndex(component);
    } catch (err) {
      _logger().default.error(`search.indexer found an issue while indexing. Error: ${err}`);

      console.warn(err); // eslint-disable-line // TODO - handle this error

      return Promise.resolve(component);
    }
  });
  return _index.apply(this, arguments);
}

function indexAll(_x3, _x4) {
  return _indexAll.apply(this, arguments);
}

function _indexAll() {
  _indexAll = (0, _bluebird().coroutine)(function* (path, components) {
    if (!components) return Promise.reject('The scope is empty');

    _logger().default.debug(`indexing all, scope path ${path}`);

    indexInstance = yield _serverlessIndex().default.initializeIndex(path);

    _serverlessIndex().default.deleteDb(path);

    const results = addAllToLocalIndex(components);
    return Promise.resolve(results);
  });
  return _indexAll.apply(this, arguments);
}

module.exports = {
  index,
  indexAll,
  tokenizeStr,
  stem
};