#ifndef _TILE_BASE_INTERNAL_CASE_INSENSITIVE_HASH_MAP_H
#define _TILE_BASE_INTERNAL_CASE_INSENSITIVE_HASH_MAP_H

#pragma once

#include "tile/base/string.h"

#include <array>
#include <unordered_map>

namespace tile {
namespace internal {
namespace detail {
struct CaseInsensitiveHash {
    std::size_t operator()(Slice s) const noexcept
    {
        uint64_t hash = 5381;
        for (auto &&c : s) { hash += ((hash << 5) + hash) + ToLower(c); }
        return hash;
    }
};

struct CaseInsensitiveEqualTo {
    bool operator()(Slice x, Slice y) const noexcept
    {
        if (x.size() != y.size()) { return false; }

        return EqualsIgnoreCase(x, y);
    }
};
}// namespace detail

template<typename K, typename V>
using CaseInsensitiveHashMap = std::unordered_map<K, V, detail::CaseInsensitiveHash, detail::CaseInsensitiveEqualTo>;
}// namespace internal
}// namespace tile

#endif// _TILE_BASE_INTERNAL_CASE_INSENSITIVE_HASH_MAP_H
