/*
 * Copyright 2023 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/private/SkDebug.h"
#include "modules/skunicode/src/SkUnicode_hardcoded.h"
#include <algorithm>
#include <array>
#include <utility>

bool SkUnicodeHardCodedCharProperties::isControl(SkUnichar utf8) {
    // Match u_iscntrl across Cc (Control), Cf (Format), Zl (Line Separator),
    // and Zp (Paragraph Separator) categories
    static constexpr std::array<std::pair<SkUnichar, SkUnichar>, 23> ranges {{
            {0x0000, 0x001F},
            {0x007F, 0x009F},
            {0x00AD, 0x00AD},
            {0x0600, 0x0605},
            {0x061C, 0x061C},
            {0x06DD, 0x06DD},
            {0x070F, 0x070F},
            {0x0890, 0x0891},
            {0x08E2, 0x08E2},
            {0x180E, 0x180E},
            {0x200B, 0x200F},
            {0x2028, 0x202E},
            {0x2060, 0x2064},
            {0x2066, 0x206F},
            {0xFEFF, 0xFEFF},
            {0xFFF9, 0xFFFB},
            {0x110BD, 0x110BD},
            {0x110CD, 0x110CD},
            {0x13430, 0x1343F},
            {0x1BCA0, 0x1BCA3},
            {0x1D173, 0x1D17A},
            {0xE0001, 0xE0001},
            {0xE0020, 0xE007F},
    }};
    // Ranges are sorted in ascending order, allowing early exit once utf8 precedes r.first
    for (const auto& r : ranges) {
        if (utf8 < r.first) {
            return false;
        }
        if (utf8 <= r.second) {
            return true;
        }
    }
    return false;
}

bool SkUnicodeHardCodedCharProperties::isWhitespace(SkUnichar unichar) {
    // Include ASCII information separators U+001C..U+001F (FS..US) to match u_isWhitespace
    static constexpr std::array<SkUnichar, 25> whitespaces {
            0x0009, // character tabulation
            0x000A, // line feed
            0x000B, // line tabulation
            0x000C, // form feed
            0x000D, // carriage return
            0x001C, // file separator
            0x001D, // group separator
            0x001E, // record separator
            0x001F, // unit separator
            0x0020, // space
          //0x0085, // next line
          //0x00A0, // no-break space
            0x1680, // ogham space mark
            0x2000, // en quad
            0x2001, // em quad
            0x2002, // en space
            0x2003, // em space
            0x2004, // three-per-em space
            0x2005, // four-per-em space
            0x2006, // six-per-em space
          //0x2007, // figure space
            0x2008, // punctuation space
            0x2009, // thin space
            0x200A, // hair space
            0x2028, // line separator
            0x2029, // paragraph separator
          //0x202F, // narrow no-break space
            0x205F, // medium mathematical space
            0x3000};// ideographic space
    return std::find(whitespaces.begin(), whitespaces.end(), unichar) != whitespaces.end();
}

bool SkUnicodeHardCodedCharProperties::isSpace(SkUnichar unichar) {
    // Include ASCII information separators U+001C..U+001F (FS..US) to match u_isspace
    static constexpr std::array<SkUnichar, 29> spaces {
            0x0009, // character tabulation
            0x000A, // line feed
            0x000B, // line tabulation
            0x000C, // form feed
            0x000D, // carriage return
            0x001C, // file separator
            0x001D, // group separator
            0x001E, // record separator
            0x001F, // unit separator
            0x0020, // space
            0x0085, // next line
            0x00A0, // no-break space
            0x1680, // ogham space mark
            0x2000, // en quad
            0x2001, // em quad
            0x2002, // en space
            0x2003, // em space
            0x2004, // three-per-em space
            0x2005, // four-per-em space
            0x2006, // six-per-em space
            0x2007, // figure space
            0x2008, // punctuation space
            0x2009, // thin space
            0x200A, // hair space
            0x2028, // line separator
            0x2029, // paragraph separator
            0x202F, // narrow no-break space
            0x205F, // medium mathematical space
            0x3000}; // ideographic space
    return std::find(spaces.begin(), spaces.end(), unichar) != spaces.end();
}

bool SkUnicodeHardCodedCharProperties::isTabulation(SkUnichar utf8) {
    return utf8 == '\t';
}

bool SkUnicodeHardCodedCharProperties::isHardBreak(SkUnichar utf8) {
    // Match UAX #14 LF (U+000A) and BK (U+000B, U+000C, U+2028, U+2029) mandatory line breaks
    return utf8 == '\n' || utf8 == '\v' || utf8 == '\f' ||
           utf8 == u'\u2028' || utf8 == u'\u2029';
}

bool SkUnicodeHardCodedCharProperties::IsDefaultIgnorable(SkUnichar utf8) {
    // Match UCHAR_DEFAULT_IGNORABLE_CODE_POINT across all Unicode code points
    static constexpr std::array<std::pair<SkUnichar, SkUnichar>, 17> ranges {{
            {0x00AD, 0x00AD},
            {0x034F, 0x034F},
            {0x061C, 0x061C},
            {0x115F, 0x1160},
            {0x17B4, 0x17B5},
            {0x180B, 0x180F},
            {0x200B, 0x200F},
            {0x202A, 0x202E},
            {0x2060, 0x206F},
            {0x3164, 0x3164},
            {0xFE00, 0xFE0F},
            {0xFEFF, 0xFEFF},
            {0xFFA0, 0xFFA0},
            {0xFFF0, 0xFFF8},
            {0x1BCA0, 0x1BCA3},
            {0x1D173, 0x1D17A},
            {0xE0000, 0xE0FFF},
    }};
    auto it = std::ranges::lower_bound(
            ranges, utf8, {}, &std::pair<SkUnichar, SkUnichar>::second);
    return it != ranges.end() && utf8 >= it->first;
}

bool SkUnicodeHardCodedCharProperties::isDefaultIgnorable(SkUnichar utf8) {
    return IsDefaultIgnorable(utf8);
}

bool SkUnicodeHardCodedCharProperties::isEmoji(SkUnichar unichar) {
    if (unichar == '#' || unichar == '*' || (unichar >= '0' && unichar <= '9')) {
        return true;
    }
    static constexpr std::pair<SkUnichar, SkUnichar> emojiRanges[] = {
        {0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122}, {0x2139, 0x2139},
        {0x2194, 0x2199}, {0x21A9, 0x21AA}, {0x2300, 0x23FF}, {0x25AA, 0x25AB},
        {0x25B6, 0x25B6}, {0x25C0, 0x25C0}, {0x25FB, 0x25FE}, {0x2600, 0x27BF},
        {0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C}, {0x2B50, 0x2B50},
        {0x2B55, 0x2B55}, {0x3030, 0x3030}, {0x303D, 0x303D}, {0x3297, 0x3297},
        {0x3299, 0x3299}, {0x1F000, 0x1F02F}, {0x1F0A0, 0x1F0FF}, {0x1F100, 0x1F64F},
        {0x1F680, 0x1F6FF}, {0x1F700, 0x1F77F}, {0x1F780, 0x1F7FF}, {0x1F800, 0x1F8FF},
        {0x1F900, 0x1FAFF}
    };
    for (const auto& r : emojiRanges) {
        if (unichar >= r.first && unichar <= r.second) {
            return true;
        }
    }
    return false;
}

bool SkUnicodeHardCodedCharProperties::isEmojiComponent(SkUnichar unichar) {
    return (unichar >= 0x1F3FB && unichar <= 0x1F3FF) ||
           (unichar >= 0x1F1E6 && unichar <= 0x1F1FF) ||
           unichar == 0x200D || unichar == 0xFE0F;
}

bool SkUnicodeHardCodedCharProperties::isEmojiModifier(SkUnichar unichar) {
    return unichar >= 0x1F3FB && unichar <= 0x1F3FF;
}

bool SkUnicodeHardCodedCharProperties::isEmojiModifierBase(SkUnichar unichar) {
    return this->isEmoji(unichar) && !this->isEmojiModifier(unichar);
}

bool SkUnicodeHardCodedCharProperties::isRegionalIndicator(SkUnichar unichar) {
    return unichar >= 0x1F1E6 && unichar <= 0x1F1FF;
}

bool SkUnicodeHardCodedCharProperties::isIdeographic(SkUnichar unichar) {
    static constexpr std::array<std::pair<SkUnichar, SkUnichar>, 8> ranges {{
          {4352,   4607}, // Hangul Jamo
          {11904, 42191}, // CJK_Radicals
          {43072, 43135}, // Phags_Pa
          {44032, 55215}, // Hangul_Syllables
          {63744, 64255}, // CJK_Compatibility_Ideographs
          {65072, 65103}, // CJK_Compatibility_Forms
          {65381, 65500}, // Katakana_Hangul_Halfwidth
          {131072, 196607}// Supplementary_Ideographic_Plane
    }};
    for (auto range : ranges) {
        // Block upper bounds in ranges are inclusive codepoints (e.g. U+11FF, U+D7AF)
        if (range.first <= unichar && range.second >= unichar) {
            return true;
        }
    }
    return false;
}
