
const Client = require('node-rest-client').Client;
const httpClient = new Client();
const TestEnv = require('./test-env');
const testConfig = TestEnv.testConfig;
const config = testConfig.elasticsearch;

let client = null;
let index = null;

getESConnection = () => {
    const { Client } = require('@elastic/elasticsearch');
    return new Client({ node: 'http://' + config.host });
};

getClient = () => {
  if(client == null){
    index = config.indexName;
    client = getESConnection();
  }
  return client;
};

module.exports = {

  indexOne : async (document, client) => {
    const _id = document._id.toHexString ? document._id.toHexString() : document._id;
    delete document._id;
    if(!client){
      client = getClient();
    }
    const options = {
      "index": index,
      "id": _id,
      "body": document
    };
    if (type){
        options.type = type;
    }
    // return client.index(options);
    await new Promise((resolve, reject) => {
      client.index(options, function(err, res) {
        if (err) {
          reject(err);
        } else {
          resolve();
        }
      });
    });

  },

  index : async (documents, client) => {

    if(!client){
      client = getClient();
    }

    if (!Array.isArray(documents)) {
      documents = [documents];
    }

    documents.forEach(document => {
      const _id = document._id.toHexString ? document._id.toHexString() : document._id;
      delete document._id;
      document.id = _id;
      // sanitize
      if (document.systemHeader.serverDate && document.systemHeader.serverDate.$date) {
        document.systemHeader.serverDate = document.systemHeader.serverDate.$date;
      }
    });

    let body = documents.map(doc => [{ index: {  _index: index, _id: doc.id} }, doc]);
    body = body.reduce((acc, val) => acc.concat(val), []);
    if(!client){
      client = getClient();
    }
    const bulkResponse = await client.bulk({ refresh: false, body });
    for (const item of bulkResponse.body.items) {
      if (item.index.error) {
        logger.error(item.index.error.reason);
      }
    }
    await new Promise(resolve => setTimeout(resolve, 2000));
    const { body: resp } = await client.count({ index: index });
    logger.info(`Inserted ${resp.count} of ${documents.length}`);
  },

  createESIndex : async () => {
    const template = TestEnv.elasticIndexTemplate;
    if(!client){
      client = getClient();
    }
    await client.indices.create({
      index,
      body: template
    }, { ignore: [400] });
  },

  deleteTestDBIndex : () => {
    return new Promise((resolve, reject) => {
      const url = `http://${config.host}/${config.indexName}?pretty`;
      const req = httpClient.delete(url, function (data, response) {
        resolve({data, response});
      });
      req.on('error', function (err) {
        reject(err);
      });
    });
  },

  count: async () => {
    if(!client){
      client = getClient();
    }
    const { body: resp } = await client.count({ index: index });
    return resp.count;
  }
};
