/*
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

/**
 * @file aws_auth_v4.cc
 * @brief AWS Auth v4 signing utility.
 * @see aws_auth_v4.h
 */

#include <cstring>        /* strlen() */
#include <string>         /* stoi() */
#include <ctime>          /* strftime(), time(), gmtime_r() */
#include <iomanip>        /* std::setw */
#include <sstream>        /* std::stringstream */
#include <openssl/sha.h>  /* SHA(), sha256_Update(), SHA256_Final, etc. */
#include <openssl/hmac.h> /* HMAC() */

#ifdef AWS_AUTH_V4_DETAILED_DEBUG_OUTPUT
#include <iostream>
#endif

#include "aws_auth_v4.h"

/**
 * @brief Lower-case Base16 encode a character string (hexadecimal format)
 *
 * @see AWS spec: http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
 * Base16 RFC4648: https://tools.ietf.org/html/rfc4648#section-8
 *
 * @param in ptr to an input counted string to be base16 encoded.
 * @param inLen input character string length
 * @return base16 encoded string.
 */
String
base16Encode(const char *in, size_t inLen)
{
  if (nullptr == in || inLen == 0) {
    return {};
  }

  std::stringstream result;

  const char *src    = in;
  const char *srcEnd = in + inLen;

  while (src < srcEnd) {
    result << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>((*src) & 0xFF);
    src++;
  }
  return result.str();
}

/**
 * @brief URI-encode a character string (AWS specific version, see spec)
 *
 * @see AWS spec: http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
 *
 * @todo Consider reusing / converting to TSStringPercentEncode() using a custom map to account for the AWS specific rules.
 *       Currently we don't build a library/archive so we could link with the unit-test binary. Also using
 *       different sets of encode/decode functions during runtime and unit-testing did not seem as a good idea.
 * @param in string to be URI encoded
 * @param isObjectName if true don't encode '/', keep it as it is.
 * @return encoded string.
 */
String
uriEncode(const String &in, bool isObjectName)
{
  std::stringstream result;

  for (char i : in) {
    if (isalnum(i) || i == '-' || i == '_' || i == '.' || i == '~') {
      /* URI encode every byte except the unreserved characters:
       * 'A'-'Z', 'a'-'z', '0'-'9', '-', '.', '_', and '~'. */
      result << i;
    } else if (i == ' ') {
      /* The space character is a reserved character and must be encoded as "%20" (and not as "+"). */
      result << "%20";
    } else if (isObjectName && i == '/') {
      /* Encode the forward slash character, '/', everywhere except in the object key name. */
      result << "/";
    } else {
      /* Letters in the hexadecimal value must be upper-case, for example "%1A". */
      result << "%" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(i);
    }
  }

  return result.str();
}

/**
 * @brief checks if the string is URI-encoded (AWS specific encoding version, see spec)
 *
 * @see AWS spec: http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
 *
 * @note According to the following RFC if the string is encoded and contains '%' it should
 *       be followed by 2 hexadecimal symbols otherwise '%' should be encoded with %25:
 *          https://tools.ietf.org/html/rfc3986#section-2.1
 *
 * @param in string to be URI checked
 * @param isObjectName if true encoding didn't encode '/', kept it as it is.
 * @return true if encoded, false not encoded.
 */
bool
isUriEncoded(const String &in, bool isObjectName)
{
  for (size_t pos = 0; pos < in.length(); pos++) {
    char c = in[pos];

    if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
      /* found a unreserved character which should not have been be encoded regardless
       * 'A'-'Z', 'a'-'z', '0'-'9', '-', '.', '_', and '~'.  */
      continue;
    }

    if (' ' == c) {
      /* space should have been encoded with %20 if the string was encoded */
      return false;
    }

    if ('/' == c && !isObjectName) {
      /* if this is not an object name '/' should have been encoded */
      return false;
    }

    if ('%' == c) {
      if (pos + 2 < in.length() && std::isxdigit(in[pos + 1]) && std::isxdigit(in[pos + 2])) {
        /* if string was encoded we should have exactly 2 hexadecimal chars following it */
        return true;
      } else {
        /* lonely '%' should have been encoded with %25 according to the RFC so likely not encoded */
        return false;
      }
    }
  }

  return false;
}

String
canonicalEncode(const String &in, bool isObjectName)
{
  String canonical;
  if (!isUriEncoded(in, isObjectName)) {
    /* Not URI-encoded */
    canonical = uriEncode(in, isObjectName);
  } else {
    /* URI-encoded, then don't encode since AWS does not encode which is not mentioned in the spec,
     * asked AWS, still waiting for confirmation */
    canonical = in;
  }

  return canonical;
}

/**
 * @brief trim the white-space character from the beginning and the end of the string ("in-place", just moving pointers around)
 *
 * @param in ptr to an input string
 * @param inLen input character count
 * @param newLen trimmed string character count.
 * @return pointer to the trimmed string.
 */
const char *
trimWhiteSpaces(const char *in, size_t inLen, size_t &newLen)
{
  if (nullptr == in || inLen == 0) {
    return in;
  }

  const char *first = in;
  while (size_t(first - in) < inLen && isspace(*first)) {
    first++;
  }

  const char *last = in + inLen - 1;
  while (last > in && isspace(*last)) {
    last--;
  }

  newLen = last - first + 1;
  return first;
}

/**
 * @brief Trim white spaces from beginning and end.
 * @returns trimmed string
 */
String
trimWhiteSpaces(const String &s)
{
  /* @todo do this better? */
  static const String whiteSpace = " \t\n\v\f\r";
  size_t start                   = s.find_first_not_of(whiteSpace);
  if (String::npos == start) {
    return String();
  }
  size_t stop = s.find_last_not_of(whiteSpace);
  return s.substr(start, stop - start + 1);
}

/*
 * Group of static inline helper function for less error prone parameter handling and unit test logging.
 */
inline static void
sha256Update(SHA256_CTX *ctx, const char *in, size_t inLen)
{
  SHA256_Update(ctx, in, inLen);
#ifdef AWS_AUTH_V4_DETAILED_DEBUG_OUTPUT
  std::cout << String(in, inLen);
#endif
}

inline static void
sha256Update(SHA256_CTX *ctx, const char *in)
{
  sha256Update(ctx, in, strlen(in));
}

inline static void
sha256Update(SHA256_CTX *ctx, const String &in)
{
  sha256Update(ctx, in.c_str(), in.length());
}

inline static void
sha256Final(unsigned char hex[SHA256_DIGEST_LENGTH], SHA256_CTX *ctx)
{
  SHA256_Final(hex, ctx);
}

/**
 * @brief: Payload SHA 256 = Hex(SHA256Hash(<payload>) (no new-line char at end)
 *
 * @todo support for signing of PUSH, POST content / payload
 * @param signPayload specifies whether the content / payload should be signed
 * @return signature of the content or "UNSIGNED-PAYLOAD" to mark that the payload is not signed
 */
String
getPayloadSha256(bool signPayload)
{
  static const String UNSIGNED_PAYLOAD("UNSIGNED-PAYLOAD");

  if (!signPayload) {
    return UNSIGNED_PAYLOAD;
  }

  unsigned char payloadHash[SHA256_DIGEST_LENGTH];
  SHA256(reinterpret_cast<const unsigned char *>(""), 0, payloadHash); /* empty content */

  return base16Encode(reinterpret_cast<char *>(payloadHash), SHA256_DIGEST_LENGTH);
}

/**
 * @brief Get Canonical Uri SHA256 Hash
 *
 * Hex(SHA256Hash(<CanonicalRequest>))
 * AWS spec: http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
 *
 * @param api an TS API wrapper that will provide interface to HTTP request elements (method, path, query, headers, etc).
 * @param signPayload specifies if the content / payload should be signed.
 * @param includeHeaders headers that must be signed
 * @param excludeHeaders headers that must not be signed
 * @param signedHeaders a reference to a string to which the signed headers names will be appended
 * @return SHA256 hash of the canonical request.
 */
String
getCanonicalRequestSha256Hash(TsInterface &api, bool signPayload, const StringSet &includeHeaders, const StringSet &excludeHeaders,
                              String &signedHeaders)
{
  int length;
  const char *str = nullptr;
  unsigned char canonicalRequestSha256Hash[SHA256_DIGEST_LENGTH];
  SHA256_CTX canonicalRequestSha256Ctx;

  SHA256_Init(&canonicalRequestSha256Ctx);

#ifdef AWS_AUTH_V4_DETAILED_DEBUG_OUTPUT
  std::cout << "<CanonicalRequest>";
#endif

  /* <HTTPMethod>\n */
  str = api.getMethod(&length);
  sha256Update(&canonicalRequestSha256Ctx, str, length);
  sha256Update(&canonicalRequestSha256Ctx, "\n");

  /* URI Encoded Canonical URI
   * <CanonicalURI>\n */
  str = api.getPath(&length);
  String path("/");
  path.append(str, length);
  String canonicalUri = canonicalEncode(path, /* isObjectName */ true);
  sha256Update(&canonicalRequestSha256Ctx, canonicalUri);
  sha256Update(&canonicalRequestSha256Ctx, "\n");

  /* Sorted Canonical Query String
   * <CanonicalQueryString>\n */
  const char *query = api.getQuery(&length);

  StringSet paramNames;
  StringMap paramsMap;
  std::istringstream istr(String(query, length));
  String token;
  StringSet container;

  while (std::getline(istr, token, '&')) {
    String::size_type pos(token.find_first_of('='));
    String param(token.substr(0, pos == String::npos ? token.size() : pos));
    String value(pos == String::npos ? "" : token.substr(pos + 1, token.size()));

    String encodedParam = canonicalEncode(param, /* isObjectName */ false);
    paramNames.insert(encodedParam);
    paramsMap[encodedParam] = canonicalEncode(value, /* isObjectName */ false);
  }

  String queryStr;
  for (const auto &paramName : paramNames) {
    if (!queryStr.empty()) {
      queryStr.append("&");
    }
    queryStr.append(paramName);
    queryStr.append("=").append(paramsMap[paramName]);
  }
  sha256Update(&canonicalRequestSha256Ctx, queryStr);
  sha256Update(&canonicalRequestSha256Ctx, "\n");

  /* Sorted Canonical Headers
   *  <CanonicalHeaders>\n */
  StringSet signedHeadersSet;
  StringMap headersMap;

  for (HeaderIterator it = api.headerBegin(); it != api.headerEnd(); it++) {
    int nameLen;
    int valueLen;
    const char *name  = it.getName(&nameLen);
    const char *value = it.getValue(&valueLen);

    if (nullptr == name || 0 == nameLen) {
      continue;
    }

    String lowercaseName(name, nameLen);
    std::transform(lowercaseName.begin(), lowercaseName.end(), lowercaseName.begin(), ::tolower);

    /* Host, content-type and x-amx-* headers are mandatory */
    bool xAmzHeader        = (lowercaseName.length() >= X_AMZ.length() && 0 == lowercaseName.compare(0, X_AMZ.length(), X_AMZ));
    bool contentTypeHeader = (0 == CONTENT_TYPE.compare(lowercaseName));
    bool hostHeader        = (0 == HOST.compare(lowercaseName));
    if (!xAmzHeader && !contentTypeHeader && !hostHeader) {
      /* Skip internal headers (starting with '@'*/
      if ('@' == name[0] /* exclude internal headers */) {
        continue;
      }

      /* @todo do better here, since iterating over the headers in ATS is known to be less efficient,
       * come up with a better way if include headers set is non-empty */
      bool include =
        (!includeHeaders.empty() && includeHeaders.end() != includeHeaders.find(lowercaseName)); /* requested to be included */
      bool exclude =
        (!excludeHeaders.empty() && excludeHeaders.end() != excludeHeaders.find(lowercaseName)); /* requested to be excluded */

      if ((includeHeaders.empty() && exclude) || (!includeHeaders.empty() && (!include || exclude))) {
#ifdef AWS_AUTH_V4_DETAILED_DEBUG_OUTPUT
        std::cout << "ignore header: " << String(name, nameLen) << std::endl;
#endif
        continue;
      }
    }

    size_t trimValueLen   = 0;
    const char *trimValue = trimWhiteSpaces(value, valueLen, trimValueLen);

    signedHeadersSet.insert(lowercaseName);
    if (headersMap.find(lowercaseName) == headersMap.end()) {
      headersMap[lowercaseName] = String(trimValue, trimValueLen);
    } else {
      headersMap[lowercaseName].append(",").append(String(trimValue, trimValueLen));
    }
  }

  for (const auto &it : signedHeadersSet) {
    sha256Update(&canonicalRequestSha256Ctx, it);
    sha256Update(&canonicalRequestSha256Ctx, ":");
    sha256Update(&canonicalRequestSha256Ctx, headersMap[it]);
    sha256Update(&canonicalRequestSha256Ctx, "\n");
  }
  sha256Update(&canonicalRequestSha256Ctx, "\n");

  for (const auto &it : signedHeadersSet) {
    if (!signedHeaders.empty()) {
      signedHeaders.append(";");
    }
    signedHeaders.append(it);
  }

  sha256Update(&canonicalRequestSha256Ctx, signedHeaders);
  sha256Update(&canonicalRequestSha256Ctx, "\n");

  /* Hex(SHA256Hash(<payload>) (no new-line char at end)
   * @TODO support non-empty content, i.e. POST */
  String payloadSha256Hash = getPayloadSha256(signPayload);
  sha256Update(&canonicalRequestSha256Ctx, payloadSha256Hash);

  /* Hex(SHA256Hash(<CanonicalRequest>)) */
  sha256Final(canonicalRequestSha256Hash, &canonicalRequestSha256Ctx);
#ifdef AWS_AUTH_V4_DETAILED_DEBUG_OUTPUT
  std::cout << "</CanonicalRequest>" << std::endl;
#endif
  return base16Encode(reinterpret_cast<char *>(canonicalRequestSha256Hash), SHA256_DIGEST_LENGTH);
}

/**
 * @brief Default AWS entry-point host name to region based on (S3):
 *
 * @see http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
 * it is used to get the region programmatically  w/o configuration
 * parameters and can (meant to) be overwritten if necessary.
 * @todo may be if one day AWS naming/mapping becomes 100% consistent
 * we could just extract (calculate) the right region from hostname.
 */
const StringMap
createDefaultRegionMap()
{
  StringMap m;
  /* us-east-2 */
  m["s3.us-east-2.amazonaws.com"]           = "us-east-2";
  m["s3-us-east-2.amazonaws.com"]           = "us-east-2";
  m["s3.dualstack.us-east-2.amazonaws.com"] = "us-east-2";
  /* "us-east-1" */
  m["s3.amazonaws.com"]                     = "us-east-1";
  m["s3.us-east-1.amazonaws.com"]           = "us-east-1";
  m["s3-external-1.amazonaws.com"]          = "us-east-1";
  m["s3.dualstack.us-east-1.amazonaws.com"] = "us-east-1";
  /* us-west-1 */
  m["s3.us-west-1.amazonaws.com"]           = "us-west-1";
  m["s3-us-west-1.amazonaws.com"]           = "us-west-1";
  m["s3.dualstack.us-west-1.amazonaws.com"] = "us-west-1";
  /* us-west-2 */
  m["s3.us-west-2.amazonaws.com"]           = "us-west-2";
  m["s3-us-west-2.amazonaws.com"]           = "us-west-2";
  m["s3.dualstack.us-west-2.amazonaws.com"] = "us-west-2";
  /* ap-south-1 */
  m["s3.ap-south-1.amazonaws.com"]           = "ap-south-1";
  m["s3-ap-south-1.amazonaws.com"]           = "ap-south-1";
  m["s3.dualstack.ap-south-1.amazonaws.com"] = "ap-south-1";
  /* ap-northeast-3 */
  m["s3.ap-northeast-3.amazonaws.com"]           = "ap-northeast-3";
  m["s3-ap-northeast-3.amazonaws.com"]           = "ap-northeast-3";
  m["s3.dualstack.ap-northeast-3.amazonaws.com"] = "ap-northeast-3";
  /* ap-northeast-2 */
  m["s3.ap-northeast-2.amazonaws.com"]           = "ap-northeast-2";
  m["s3-ap-northeast-2.amazonaws.com"]           = "ap-northeast-2";
  m["s3.dualstack.ap-northeast-2.amazonaws.com"] = "ap-northeast-2";
  /* ap-southeast-1 */
  m["s3.ap-southeast-1.amazonaws.com"]           = "ap-southeast-1";
  m["s3-ap-southeast-1.amazonaws.com"]           = "ap-southeast-1";
  m["s3.dualstack.ap-southeast-1.amazonaws.com"] = "ap-southeast-1";
  /* ap-southeast-2 */
  m["s3.ap-southeast-2.amazonaws.com"]           = "ap-southeast-2";
  m["s3-ap-southeast-2.amazonaws.com"]           = "ap-southeast-2";
  m["s3.dualstack.ap-southeast-2.amazonaws.com"] = "ap-southeast-2";
  /* ap-northeast-1 */
  m["s3.ap-northeast-1.amazonaws.com"]           = "ap-northeast-1";
  m["s3-ap-northeast-1.amazonaws.com"]           = "ap-northeast-1";
  m["s3.dualstack.ap-northeast-1.amazonaws.com"] = "ap-northeast-1";
  /* ca-central-1 */
  m["s3.ca-central-1.amazonaws.com"]           = "ca-central-1";
  m["s3-ca-central-1.amazonaws.com"]           = "ca-central-1";
  m["s3.dualstack.ca-central-1.amazonaws.com"] = "ca-central-1";
  /* cn-north-1 */
  m["s3.cn-north-1.amazonaws.com.cn"] = "cn-north-1";
  /* cn-northwest-1 */
  m["s3.cn-northwest-1.amazonaws.com.cn"] = "cn-northwest-1";
  /* eu-central-1 */
  m["s3.eu-central-1.amazonaws.com"]           = "eu-central-1";
  m["s3-eu-central-1.amazonaws.com"]           = "eu-central-1";
  m["s3.dualstack.eu-central-1.amazonaws.com"] = "eu-central-1";
  /* eu-west-1 */
  m["s3.eu-west-1.amazonaws.com"]           = "eu-west-1";
  m["s3-eu-west-1.amazonaws.com"]           = "eu-west-1";
  m["s3.dualstack.eu-west-1.amazonaws.com"] = "eu-west-1";
  /* eu-west-2 */
  m["s3.eu-west-2.amazonaws.com"]           = "eu-west-2";
  m["s3-eu-west-2.amazonaws.com"]           = "eu-west-2";
  m["s3.dualstack.eu-west-2.amazonaws.com"] = "eu-west-2";
  /* eu-west-3 */
  m["s3.eu-west-3.amazonaws.com"]           = "eu-west-3";
  m["s3-eu-west-3.amazonaws.com"]           = "eu-west-3";
  m["s3.dualstack.eu-west-3.amazonaws.com"] = "eu-west-3";
  /* sa-east-1 */
  m["s3.sa-east-1.amazonaws.com"]           = "sa-east-1";
  m["s3-sa-east-1.amazonaws.com"]           = "sa-east-1";
  m["s3.dualstack.sa-east-1.amazonaws.com"] = "sa-east-1";
  /* default "us-east-1" * */
  m[""] = "us-east-1";
  return m;
}
const StringMap defaultDefaultRegionMap = createDefaultRegionMap();

/**
 * @description default list of headers to be excluded from the signing
 */
const StringSet
createDefaultExcludeHeaders()
{
  StringSet m;
  /* exclude headers that are meant to be changed */
  m.insert("x-forwarded-for");
  m.insert("forwarded");
  m.insert("via");
  return m;
}
const StringSet defaultExcludeHeaders = createDefaultExcludeHeaders();

/**
 * @description default list of headers to be included in the signing
 */
const StringSet
createDefaultIncludeHeaders()
{
  StringSet m;
  return m;
}
const StringSet defaultIncludeHeaders = createDefaultIncludeHeaders();

/**
 * @brief Get AWS (S3) region from the entry-point
 *
 * @see Implementation based on the following:
 *   http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
 *   http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
 *
 * @param regionMap map containing entry-point to region mapping
 * @param entryPoint entry-point name
 * @param entryPointLen - entry point string length
 */
String
getRegion(const StringMap &regionMap, const char *entryPoint, size_t entryPointLen)
{
  String region;
  size_t dot = String::npos;
  String hostname(entryPoint, entryPointLen);

  /* Start looking for a match from the top-level domain backwards to keep the mapping generic
   * (so we can override it if we need later) */
  do {
    String name;
    dot = hostname.rfind('.', dot - 1);
    if (String::npos != dot) {
      name = hostname.substr(dot + 1);
    } else {
      name = hostname;
    }
    if (regionMap.end() != regionMap.find(name)) {
      region = regionMap.at(name);
      break;
    }
  } while (String::npos != dot);

  if (region.empty() && regionMap.end() != regionMap.find("")) {
    region = regionMap.at(""); /* default region if nothing matches */
  }

  return region;
}

/**
 * @brief Constructs the string to sign
 *
 * @see AWS spec: http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html

 * @param entryPoint  entry-point name
 * @param entryPointLen entry-point name length
 * @param dateTime - ISO 8601 time
 * @param dateTimeLen - ISO 8601 time length
 * @param region AWS region name
 * @param region AWS region name length
 * @param service service name
 * @param serviceLen service name length
 * @param sha256Hash canonical request SHA 256 hash
 * @param sha256HashLen canonical request SHA 256 hash length
 * @returns the string to sign
 */
String
getStringToSign(const char *entryPoint, size_t EntryPointLen, const char *dateTime, size_t dateTimeLen, const char *region,
                size_t regionLen, const char *service, size_t serviceLen, const char *sha256Hash, size_t sha256HashLen)
{
  String stringToSign;

  /* AWS4-HMAC-SHA256\n (hard-coded, other values? */
  stringToSign.append("AWS4-HMAC-SHA256\n");

  /* time stamp in ISO8601 format: <YYYYMMDDTHHMMSSZ>\n */
  stringToSign.append(dateTime, dateTimeLen);
  stringToSign.append("\n");

  /* Scope: date.Format(<YYYYMMDD>) + "/" + <region> + "/" + <service> + "/aws4_request" */
  stringToSign.append(dateTime, 8); /* Get only the YYYYMMDD */
  stringToSign.append("/");
  stringToSign.append(region, regionLen);
  stringToSign.append("/");
  stringToSign.append(service, serviceLen);
  stringToSign.append("/aws4_request\n");
  stringToSign.append(sha256Hash, sha256HashLen);

  return stringToSign;
}

/**
 * @brief Calculates the final signature based on the following parameters and base16 encodes it.
 *
 * signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<awsSecret>", <dateTime>),
 *                   <awsRegion>), <awsService>),"aws4_request")
 *
 * @see AWS spec: http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
 *
 * @param awsSecret AWS secret
 * @param awsSecretLen AWS secret length
 * @param awsRegion AWS region
 * @param awsRegionLen AWS region length
 * @param awsService AWS Service name
 * @param awsServiceLen AWS service name length
 * @param dateTime ISO8601 date/time
 * @param dateTimeLen ISO8601 date/time length
 * @param stringToSign string to sign
 * @param stringToSignLen length of the string to sign
 * @param base16Signature output buffer where the base16 signature will be stored
 * @param base16SignatureLen size of the signature buffer = EVP_MAX_MD_SIZE (at least)
 *
 * @return number of characters written to the output buffer
 */
size_t
getSignature(const char *awsSecret, size_t awsSecretLen, const char *awsRegion, size_t awsRegionLen, const char *awsService,
             size_t awsServiceLen, const char *dateTime, size_t dateTimeLen, const char *stringToSign, size_t stringToSignLen,
             char *signature, size_t signatureLen)
{
  unsigned int dateKeyLen = EVP_MAX_MD_SIZE;
  unsigned char dateKey[EVP_MAX_MD_SIZE];
  unsigned int dateRegionKeyLen = EVP_MAX_MD_SIZE;
  unsigned char dateRegionKey[EVP_MAX_MD_SIZE];
  unsigned int dateRegionServiceKeyLen = EVP_MAX_MD_SIZE;
  unsigned char dateRegionServiceKey[EVP_MAX_MD_SIZE];
  unsigned int signingKeyLen = EVP_MAX_MD_SIZE;
  unsigned char signingKey[EVP_MAX_MD_SIZE];

  size_t keyLen = 4 + awsSecretLen;
  char key[keyLen];
  memcpy(key, "AWS4", 4);
  memcpy(key + 4, awsSecret, awsSecretLen);

  unsigned int len = signatureLen;
  if (HMAC(EVP_sha256(), key, keyLen, (unsigned char *)dateTime, dateTimeLen, dateKey, &dateKeyLen) &&
      HMAC(EVP_sha256(), dateKey, dateKeyLen, (unsigned char *)awsRegion, awsRegionLen, dateRegionKey, &dateRegionKeyLen) &&
      HMAC(EVP_sha256(), dateRegionKey, dateRegionKeyLen, (unsigned char *)awsService, awsServiceLen, dateRegionServiceKey,
           &dateRegionServiceKeyLen) &&
      HMAC(EVP_sha256(), dateRegionServiceKey, dateRegionServiceKeyLen, reinterpret_cast<const unsigned char *>("aws4_request"), 12,
           signingKey, &signingKeyLen) &&
      HMAC(EVP_sha256(), signingKey, signingKeyLen, (unsigned char *)stringToSign, stringToSignLen,
           reinterpret_cast<unsigned char *>(signature), &len)) {
    return len;
  }

  return 0;
}

/**
 * @brief formats the time stamp in ISO8601 format: <YYYYMMDDTHHMMSSZ>
 */
size_t
getIso8601Time(time_t *now, char *dateTime, size_t dateTimeLen)
{
  struct tm tm;
  return strftime(dateTime, dateTimeLen, "%Y%m%dT%H%M%SZ", gmtime_r(now, &tm));
}

/**
 * @brief formats the time stamp in ISO8601 format: <YYYYMMDDTHHMMSSZ>
 */
const char *
AwsAuthV4::getDateTime(size_t *dateTimeLen)
{
  *dateTimeLen = sizeof(_dateTime) - 1;
  return _dateTime;
}

/**
 * @brief: HTTP content / payload SHA 256 = Hex(SHA256Hash(<payload>)
 * @return signature of the content or "UNSIGNED-PAYLOAD" to mark that the payload is not signed
 */
String
AwsAuthV4::getPayloadHash()
{
  return getPayloadSha256(_signPayload);
}

/**
 * @brief Get the value of the Authorization header (AWS authorization) v4
 * @return the Authorization header value
 */
String
AwsAuthV4::getAuthorizationHeader()
{
  String signedHeaders;
  String canonicalReq = getCanonicalRequestSha256Hash(_api, _signPayload, _includedHeaders, _excludedHeaders, signedHeaders);

  int hostLen      = 0;
  const char *host = _api.getHost(&hostLen);

  String awsRegion = getRegion(_regionMap, host, hostLen);

  String stringToSign = getStringToSign(host, hostLen, _dateTime, sizeof(_dateTime) - 1, awsRegion.c_str(), awsRegion.length(),
                                        _awsService, _awsServiceLen, canonicalReq.c_str(), canonicalReq.length());
#ifdef AWS_AUTH_V4_DETAILED_DEBUG_OUTPUT
  std::cout << "<StringToSign>" << stringToSign << "</StringToSign>" << std::endl;
#endif

  char signature[EVP_MAX_MD_SIZE];
  size_t signatureLen =
    getSignature(_awsSecretAccessKey, _awsSecretAccessKeyLen, awsRegion.c_str(), awsRegion.length(), _awsService, _awsServiceLen,
                 _dateTime, 8, stringToSign.c_str(), stringToSign.length(), signature, EVP_MAX_MD_SIZE);

  String base16Signature = base16Encode(signature, signatureLen);
#ifdef AWS_AUTH_V4_DETAILED_DEBUG_OUTPUT
  std::cout << "<SignatureProvided>" << base16Signature << "</SignatureProvided>" << std::endl;
#endif

  std::stringstream authorizationHeader;
  authorizationHeader << "AWS4-HMAC-SHA256 ";
  authorizationHeader << "Credential=" << String(_awsAccessKeyId, _awsAccessKeyIdLen) << "/" << String(_dateTime, 8) << "/"
                      << awsRegion << "/" << String(_awsService, _awsServiceLen) << "/"
                      << "aws4_request"
                      << ",";
  authorizationHeader << "SignedHeaders=" << signedHeaders << ",";
  authorizationHeader << "Signature=" << base16Signature;

  return authorizationHeader.str();
}

/**
 * @brief Authorization v4 constructor
 *
 * @param api wrapper providing access to HTTP request elements (URI host, path, query, headers, etc.)
 * @param now current time-stamp
 * @param signPayload defines if the HTTP content / payload needs to be signed
 * @param awsAccessKeyId AWS access key ID
 * @param awsAccessKeyIdLen AWS access key ID length
 * @param awsSecretAccessKey AWS secret
 * @param awsSecretAccessKeyLen AWS secret length
 * @param awsService AWS Service name
 * @param awsServiceLen AWS service name length
 * @param includeHeaders set of headers to be signed
 * @param excludeHeaders set of headers not to be signed
 * @param regionMap entry-point to AWS region mapping
 */
AwsAuthV4::AwsAuthV4(TsInterface &api, time_t *now, bool signPayload, const char *awsAccessKeyId, size_t awsAccessKeyIdLen,
                     const char *awsSecretAccessKey, size_t awsSecretAccessKeyLen, const char *awsService, size_t awsServiceLen,
                     const StringSet &includedHeaders, const StringSet &excludedHeaders, const StringMap &regionMap)
  : _api(api),
    _signPayload(signPayload),
    _awsAccessKeyId(awsAccessKeyId),
    _awsAccessKeyIdLen(awsAccessKeyIdLen),
    _awsSecretAccessKey(awsSecretAccessKey),
    _awsSecretAccessKeyLen(awsSecretAccessKeyLen),
    _awsService(awsService),
    _awsServiceLen(awsServiceLen),
    _includedHeaders(includedHeaders.empty() ? defaultIncludeHeaders : includedHeaders),
    _excludedHeaders(excludedHeaders.empty() ? defaultExcludeHeaders : excludedHeaders),
    _regionMap(regionMap.empty() ? defaultDefaultRegionMap : regionMap)
{
  getIso8601Time(now, _dateTime, sizeof(_dateTime));
}
