/**
 * 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.
 */
#ifndef LIBMINIFI_INCLUDE_IO_STRINGUTILS_H_
#define LIBMINIFI_INCLUDE_IO_STRINGUTILS_H_
#include <iostream>
#include <algorithm>
#include <sstream>
#include <vector>
#include <map>
#include "utils/FailurePolicy.h"

namespace org {
namespace apache {
namespace nifi {
namespace minifi {
namespace utils {

/**
 * Stateless String utility class.
 *
 * Design: Static class, with no member variables
 *
 * Purpose: Houses many useful string utilities.
 */
class StringUtils {
 public:
  /**
   * Converts a string to a boolean
   * Better handles mixed case.
   * @param input input string
   * @param output output string.
   */
  static bool StringToBool(std::string input, bool &output) {

    std::transform(input.begin(), input.end(), input.begin(), ::tolower);
    std::istringstream(input) >> std::boolalpha >> output;
    return output;
  }

  // Trim String utils

  /**
   * Trims a string left to right
   * @param s incoming string
   * @returns modified string
   */
  static std::string trim(std::string s) {
    return trimRight(trimLeft(s));
  }

  /**
   * Trims left most part of a string
   * @param s incoming string
   * @returns modified string
   */
  static inline std::string trimLeft(std::string s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::pointer_to_unary_function<int, int>(std::isspace))));
    return s;
  }

  /**
   * Trims a string on the right
   * @param s incoming string
   * @returns modified string
   */

  static inline std::string trimRight(std::string s) {
    s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::pointer_to_unary_function<int, int>(std::isspace))).base(), s.end());
    return s;
  }

  /**
   * Compares strings by lower casing them.
   */
  static inline bool equalsIgnoreCase(const std::string &left, const std::string right) {
    if (left.length() == right.length()) {
      return std::equal(right.begin(), right.end(), left.begin(), [](unsigned char lc, unsigned char rc) {return std::tolower(lc) == std::tolower(rc);});
    } else {
      return false;
    }
  }

  static std::vector<std::string> split(const std::string &str, const std::string &delimiter) {
    std::vector<std::string> result;
    auto curr = str.begin();
    auto end = str.end();
    auto is_func = [delimiter](int s) {
      return delimiter.at(0) == s;
    };
    while (curr != end) {
      curr = std::find_if_not(curr, end, is_func);
      if (curr == end) {
        break;
      }
      auto next = std::find_if(curr, end, is_func);
      result.push_back(std::string(curr, next));
      curr = next;
    }

    return result;
  }

  /**
   * Converts a string to a float
   * @param input input string
   * @param output output float
   * @param cp failure policy
   */
  static bool StringToFloat(std::string input, float &output, FailurePolicy cp = RETURN) {
    try {
      output = std::stof(input);
    } catch (const std::invalid_argument &ie) {
      switch (cp) {
        case RETURN:
        case NOTHING:
          return false;
        case EXIT:
          exit(1);
        case EXCEPT:
          throw ie;
      }
    } catch (const std::out_of_range &ofr) {
      switch (cp) {
        case RETURN:
        case NOTHING:
          return false;
        case EXIT:
          exit(1);
        case EXCEPT:
          throw ofr;

      }
    }

    return true;

  }

  static std::string replaceEnvironmentVariables(std::string& original_string) {
    int32_t beg_seq = 0;
    int32_t end_seq = 0;
    std::string source_string = original_string;
    do {
      beg_seq = source_string.find("${", beg_seq);
      if (beg_seq > 0 && source_string.at(beg_seq - 1) == '\\') {
        beg_seq += 2;
        continue;
      }
      if (beg_seq < 0)
        break;
      end_seq = source_string.find("}", beg_seq + 2);
      if (end_seq < 0)
        break;
      if (end_seq - (beg_seq + 2) < 0) {
        beg_seq += 2;
        continue;
      }
      const std::string env_field = source_string.substr(beg_seq + 2, end_seq - (beg_seq + 2));
      const std::string env_field_wrapped = source_string.substr(beg_seq, end_seq + 1);
      if (env_field.empty()) {
        continue;
      }
      const auto strVal = std::getenv(env_field.c_str());
      std::string env_value;
      if (strVal != nullptr)
        env_value = strVal;
      source_string = replaceAll(source_string, env_field_wrapped, env_value);
      beg_seq = 0;  // restart
    } while (beg_seq >= 0);

    source_string = replaceAll(source_string, "\\$", "$");

    return source_string;
  }

  static std::string& replaceAll(std::string& source_string, const std::string &from_string, const std::string &to_string) {
    std::size_t loc = 0;
    std::size_t lastFound;
    while ((lastFound = source_string.find(from_string, loc)) != std::string::npos) {
      source_string.replace(lastFound, from_string.size(), to_string);
      loc = lastFound + to_string.size();
    }
    return source_string;
  }

  inline static bool endsWithIgnoreCase(const std::string &value, const std::string & endString) {
    if (endString.size() > value.size())
      return false;
    return std::equal(endString.rbegin(), endString.rend(), value.rbegin(), [](unsigned char lc, unsigned char rc) {return std::tolower(lc) == std::tolower(rc);});
  }

  inline static bool endsWith(const std::string &value, const std::string & endString) {
    if (endString.size() > value.size())
      return false;
    return std::equal(endString.rbegin(), endString.rend(), value.rbegin());
  }
  
  static std::string replaceMap(std::string source_string, const std::map<std::string, std::string> &replace_map) {
    auto result_string = source_string;

    std::vector<std::pair<size_t, std::pair<size_t, std::string>>> replacements;
    for (const auto &replace_pair : replace_map) {
      size_t replace_pos = 0;
      while ((replace_pos = source_string.find(replace_pair.first, replace_pos)) != std::string::npos) {
        replacements.emplace_back(std::make_pair(replace_pos,
                                                 std::make_pair(replace_pair.first.length(), replace_pair.second)));
        replace_pos += replace_pair.first.length();
      }
    }

    std::sort(replacements.begin(), replacements.end(), [](const std::pair<size_t, std::pair<size_t, std::string>> a,
                                                           const std::pair<size_t, std::pair<size_t, std::string>> &b) {
      return a.first > b.first;
    });

    for (const auto &replacement : replacements) {
      result_string = source_string.replace(replacement.first, replacement.second.first, replacement.second.second);
    }

    return result_string;
  }

};

} /* namespace utils */
} /* namespace minifi */
} /* namespace nifi */
} /* namespace apache */
} /* namespace org */

#endif /* LIBMINIFI_INCLUDE_IO_STRINGUTILS_H_ */
