const { isNil } = require("lodash");
const aws4 = require("aws4");
const { Connection, Client } = require("@opensearch-project/opensearch");
const { defaultProvider } = require("@aws-sdk/credential-provider-node");

const createAwsConnector = (credentials, region) => {
  class AmazonConnection extends Connection {
    buildRequestObject(params) {
      const request = super.buildRequestObject(params);
      request.service = "es";
      request.region = region;
      request.headers = request.headers || {};
      request.headers["host"] = request.hostname;

      return aws4.sign(request, credentials);
    }
  }

  return {
    Connection: AmazonConnection
  };
};

const getClient = async () => {
  // We have manual configuration for OpenSearch,
  // Return a client using these custom credentials
  if (
    !isNil(process.env.OPEN_SEARCH_PASSWORD) &&
    !isNil(process.env.OPEN_SEARCH_USER) &&
    !isNil(process.env.OPEN_SEARCH_HOST) &&
    !isNil(process.env.OPEN_SEARCH_PROTOCOL)
  ) {
    // The URI is currently being stored in its entirety, so strip protocol prior to rebuilding it.
    const hostUrl = process.env.OPEN_SEARCH_HOST.replace(/^https?:\/\//i, "");
    const node = `${process.env.OPEN_SEARCH_PROTOCOL}://${process.env.OPEN_SEARCH_USER}:${process.env.OPEN_SEARCH_PASSWORD}@${hostUrl}`;

    return new Client({
      node
    });
  }

  // Default to the AWS Credentials Provider.
  const credentials = await defaultProvider()();
  return new Client({
    ...createAwsConnector(credentials, "ca-central-1"),
    node: process.env.OPEN_SEARCH_HOST
  });
};

module.exports = { getClient };
