#pragma once

#include <array>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <ctime>
#include <functional>
#include <iomanip>
#include <limits>
#include <stdexcept>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>

#include "boost/callable_traits.hpp"  // NOLINT
#include "boost/url/decode_view.hpp"  // NOLINT
#include "boost/url/parse.hpp"  // NOLINT
#include "boost/url/url.hpp"  // NOLINT
#include "boost/url/url_view.hpp"  // NOLINT
#include <nlohmann/json.hpp>

namespace crow {
namespace black_magic {

enum class TypeCode : std::uint8_t {
  Unspecified = 0,
  Integer = 1,
  UnsignedInteger = 2,
  Float = 3,
  String = 4,
  Path = 5,
  Max = 6,
};

// Remove when we have c++23
template <typename E>
constexpr typename std::underlying_type<E>::type toUnderlying(E e) noexcept {
  return static_cast<typename std::underlying_type<E>::type>(e);
}

template <typename T>
constexpr TypeCode getParameterTag() {
  if constexpr (std::is_same_v<int, T>) {
    return TypeCode::Integer;
  }
  if constexpr (std::is_same_v<char, T>) {
    return TypeCode::Integer;
  }
  if constexpr (std::is_same_v<int16_t, T>) {
    return TypeCode::Integer;
  }
  if constexpr (std::is_same_v<int32_t, T>) {
    return TypeCode::Integer;
  }
  if constexpr (std::is_same_v<int64_t, T>) {
    return TypeCode::Integer;
  }
  if constexpr (std::is_same_v<unsigned int, T>) {
    return TypeCode::UnsignedInteger;
  }
  if constexpr (std::is_same_v<unsigned char, T>) {
    return TypeCode::UnsignedInteger;
  }
  if constexpr (std::is_same_v<uint16_t, T>) {
    return TypeCode::UnsignedInteger;
  }
  if constexpr (std::is_same_v<uint32_t, T>) {
    return TypeCode::UnsignedInteger;
  }
  if constexpr (std::is_same_v<uint64_t, T>) {
    return TypeCode::UnsignedInteger;
  }
  if constexpr (std::is_same_v<double, T>) {
    return TypeCode::Float;
  }
  if constexpr (std::is_same_v<std::string, T>) {
    return TypeCode::String;
  }
  return TypeCode::Unspecified;
}

template <typename... Args>
struct computeParameterTagFromArgsList;

template <>
struct computeParameterTagFromArgsList<> {
  static constexpr int value = 0;
};

constexpr uint64_t getParameterTag(std::string_view url) {
  uint64_t tagValue = 0;
  size_t urlSegmentIndex = std::string_view::npos;

  size_t paramIndex = 0;

  for (size_t urlIndex = 0; urlIndex < url.size(); urlIndex++) {
    char character = url[urlIndex];
    if (character == '<') {
      if (urlSegmentIndex != std::string_view::npos) {
        return 0;
      }
      urlSegmentIndex = urlIndex;
    }
    if (character == '>') {
      if (urlSegmentIndex == std::string_view::npos) {
        return 0;
      }
      std::string_view tag =
          url.substr(urlSegmentIndex, urlIndex + 1 - urlSegmentIndex);

      // Note, this is a really lame way to do std::pow(6, paramIndex)
      // std::pow doesn't work in constexpr in clang.
      // Ideally in the future we'd move this to use a power of 2 packing
      // (probably 8 instead of 6) so that these just become bit shifts
      uint64_t insertIndex = 1;
      for (size_t unused = 0; unused < paramIndex; unused++) {
        insertIndex *= 6;
      }

      if (tag == "<int>") {
        tagValue += insertIndex * toUnderlying(TypeCode::Integer);
      }
      if (tag == "<uint>") {
        tagValue += insertIndex * toUnderlying(TypeCode::UnsignedInteger);
      }
      if (tag == "<float>" || tag == "<double>") {
        tagValue += insertIndex * toUnderlying(TypeCode::Float);
      }
      if (tag == "<str>" || tag == "<string>") {
        tagValue += insertIndex * toUnderlying(TypeCode::String);
      }
      if (tag == "<path>") {
        tagValue += insertIndex * toUnderlying(TypeCode::Path);
      }
      paramIndex++;
      urlSegmentIndex = std::string_view::npos;
    }
  }
  if (urlSegmentIndex != std::string_view::npos) {
    return 0;
  }
  return tagValue;
}

template <typename Arg, typename... Args>
struct computeParameterTagFromArgsList<Arg, Args...> {
  static constexpr int subValue =
      computeParameterTagFromArgsList<Args...>::value;
  static constexpr int value =
      getParameterTag<typename std::decay<Arg>::type>() != TypeCode::Unspecified
          ? static_cast<uint64_t>(subValue * toUnderlying(TypeCode::Max)) +
                static_cast<uint64_t>(
                    getParameterTag<typename std::decay<Arg>::type>())
          : subValue;
};

bool isParameterTagCompatible(uint64_t a, uint64_t b);

template <typename... T>
struct S {
  template <typename U>
  using push = S<U, T...>;
  template <typename U>
  using push_back = S<T..., U>;
  template <template <typename... Args> class U>
  using rebind = U<T...>;
};

template <typename F, typename Set>
struct CallHelper;

template <typename F, typename... Args>
struct CallHelper<F, S<Args...>> {
  template <typename F1, typename... Args1,
            typename = decltype(std::declval<F1>()(std::declval<Args1>()...))>
  static char test(int);

  template <typename...>
  static int test(...);

  static constexpr bool value = sizeof(test<F, Args...>(0)) == sizeof(char);
};

template <uint64_t N>
struct SingleTagToType {};

template <>
struct SingleTagToType<1> {
  using type = int64_t;
};

template <>
struct SingleTagToType<2> {
  using type = uint64_t;
};

template <>
struct SingleTagToType<3> {
  using type = double;
};

template <>
struct SingleTagToType<4> {
  using type = std::string;
};

template <>
struct SingleTagToType<5> {
  using type = std::string;
};

template <uint64_t Tag>
struct Arguments {
  using subarguments = typename Arguments<Tag / 6>::type;
  using type = typename subarguments::template push<
      typename SingleTagToType<Tag % 6>::type>;
};

template <>
struct Arguments<0> {
  using type = S<>;
};

template <typename T>
struct Promote {
  using type = T;
};

template <typename T>
using PromoteT = typename Promote<T>::type;

template <>
struct Promote<char> {
  using type = int64_t;
};
template <>
struct Promote<int16_t> {
  using type = int64_t;
};
template <>
struct Promote<int> {
  using type = int64_t;
};
template <>
struct Promote<int64_t> {
  using type = int64_t;
};
template <>
struct Promote<unsigned char> {
  using type = uint64_t;
};
template <>
struct Promote<uint16_t> {
  using type = uint64_t;
};
template <>
struct Promote<unsigned int> {
  using type = uint64_t;
};
template <>
struct Promote<uint64_t> {
  using type = uint64_t;
};

}  // namespace black_magic

namespace utility {

template <typename T>
struct FunctionTraits {
  template <size_t i>
  using arg = std::tuple_element_t<i, boost::callable_traits::args_t<T>>;
};

std::string base64encode(std::string_view data);

// TODO this is temporary and should be deleted once base64 is refactored out of
// crow
bool base64Decode(std::string_view input, std::string& output);

bool constantTimeStringCompare(std::string_view a, std::string_view b);

struct ConstantTimeCompare {
  bool operator()(std::string_view a, std::string_view b) const {
    return constantTimeStringCompare(a, b);
  }
};

namespace details {
inline boost::urls::url appendUrlPieces(
    boost::urls::url& url, const std::initializer_list<std::string_view> args) {
  for (std::string_view arg : args) {
    url.segments().push_back(arg);
  }
  return url;
}

inline boost::urls::url urlFromPiecesDetail(
    const std::initializer_list<std::string_view> args) {
  boost::urls::url url("/");
  appendUrlPieces(url, args);
  return url;
}
}  // namespace details

class OrMorePaths {};

template <typename... AV>
inline boost::urls::url urlFromPieces(const AV... args) {
  return details::urlFromPiecesDetail({args...});
}

template <typename... AV>
inline void appendUrlPieces(boost::urls::url& url, const AV... args) {
  details::appendUrlPieces(url, {args...});
}

namespace details {

// std::reference_wrapper<std::string> - extracts segment to variable
//                    std::string_view - checks if segment is equal to variable
using UrlSegment = std::variant<std::reference_wrapper<std::string>,
                                std::string_view, OrMorePaths>;

enum class UrlParseResult : uint8_t {
  Continue,
  Fail,
  Done,
};

class UrlSegmentMatcherVisitor {
 public:
  UrlParseResult operator()(std::string& output) {
    output = segment;
    return UrlParseResult::Continue;
  }

  UrlParseResult operator()(std::string_view expected) {
    if (segment == expected) {
      return UrlParseResult::Continue;
    }
    return UrlParseResult::Fail;
  }

  UrlParseResult operator()(OrMorePaths /*unused*/) {
    return UrlParseResult::Done;
  }

  explicit UrlSegmentMatcherVisitor(std::string_view segmentIn)
      : segment(segmentIn) {}

 private:
  std::string_view segment;
};

bool readUrlSegments(boost::urls::url_view url,  // NOLINT
                     std::initializer_list<UrlSegment>&& segments);

}  // namespace details

template <typename... Args>
inline bool readUrlSegments(boost::urls::url_view url,
                            Args&&... args)  // NOLINT
{
  return details::readUrlSegments(url, {std::forward<Args>(args)...});
}

boost::urls::url replaceUrlSegment(boost::urls::url_view urlView,  // NOLINT
                                   uint replaceLoc,
                                   std::string_view newSegment);

std::string setProtocolDefaults(boost::urls::url_view urlView);  // NOLINT

uint16_t setPortDefaults(boost::urls::url_view url);  // NOLINT

bool validateAndSplitUrl(std::string_view destUrl, std::string& urlProto,
                         std::string& host, uint16_t& port, std::string& path);

}  // namespace utility
}  // namespace crow

namespace nlohmann {
template <>
struct adl_serializer<boost::urls::url> {
  // nlohmann requires a specific casing to look these up in adl
  // NOLINTNEXTLINE(readability-identifier-naming)
  static void to_json(json& j, const boost::urls::url& url) {
    boost::urls::decode_view url_decoded{url};
    j = std::string(url_decoded.begin(), url_decoded.end());
  }
};

template <>
struct adl_serializer<boost::urls::url_view> {
  // NOLINTNEXTLINE(readability-identifier-naming,
  // performance-unnecessary-value-param)
  static void to_json(json& j, boost::urls::url_view url) {
    boost::urls::decode_view url_decoded{url};
    j = std::string(url_decoded.begin(), url_decoded.end());
  }
};
}  // namespace nlohmann
