#pragma once

#include <yandex/maps/wiki/validator/check_context.h>
#include <yandex/maps/wiki/validator/objects/name.h>

#include "name_data.h"

#include <unicode/regex.h>
#include <cstdint>
#include <string>
#include <vector>

namespace maps {
namespace wiki {
namespace validator {

class CheckContext;

namespace utils {

size_t countCodePoints(const std::string& utf8string);
bool isUpperCase(const std::string& utf8string);
std::vector<std::string> splitIntoWords(const std::string& line);

bool isNameEmpty(const std::string& name);

template<class NameCategory, class Object>
void runBasicNamesCheck(
        const Object* object, CheckContext* context,
        Severity officialNameSeverity = Severity::Error);

template<class NameCategory, class Object>
NameData namesByType(
        const Object* object,
        CheckContext* context,
        NameRelation::Type type);

template<class NameCategory>
std::set<std::string> langsFromNames(
        const std::vector<NameRelation>& names,
        CheckContext* context);

template<class NameCategory, class Object>
NameData officialNames(const Object* object, CheckContext* context);

template<class NameCategory, class Object>
bool isNamed(const Object* object, CheckContext* context);

// Regexp utils
icu::RegexPattern compilePattern(
        const std::string& regex,
        uint32_t flags = 0);

bool matchesPattern(
        const std::string& string,
        const icu::RegexPattern& pattern);

/// @brief Applies given visitor for render_label names.
/// For those languages for which render_label name is missing
/// the visitor is applied to official names.
template<class NameCategory, class Object, class NameVisitor>
void visitRenderedNames(
        const Object* object,
        CheckContext* context,
        NameVisitor visitor);

template<class NameCategory, class Object>
void runCapsNameCheck(const Object* object, CheckContext* context);

bool isValidLang(const std::string& lang);

} // namespace utils
} // namespace validator
} // namespace wiki
} // namespace maps

#define VALIDATOR_CHECKS_UTILS_NAMES_INL
#include "names-inl.h"
#undef VALIDATOR_CHECKS_UTILS_NAMES_INL
