// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
//
//  regexst.h
//
//  Copyright (C) 2004-2015, International Business Machines Corporation and others.
//  All Rights Reserved.
//
//  This file contains class RegexStaticSets
//
//  This class is internal to the regular expression implementation.
//  For the public Regular Expression API, see the file "unicode/regex.h"
//
//  RegexStaticSets groups together the common UnicodeSets that are needed
//   for compiling or executing RegularExpressions.  This grouping simplifies
//   the thread safe lazy creation and sharing of these sets across
//   all instances of regular expressions.
//
#include "unicode/utypes.h"

#if !UCONFIG_NO_REGULAR_EXPRESSIONS

#if defined(STARBOARD)
#include "starboard/client_porting/poem/assert_poem.h"
#include "starboard/client_porting/poem/string_poem.h"
#endif  // defined(STARBOARD)
#include "unicode/unistr.h"
#include "unicode/uniset.h"
#include "unicode/uchar.h"
#include "unicode/regex.h"
#include "uprops.h"
#include "cmemory.h"
#include "cstring.h"
#include "uassert.h"
#include "ucln_in.h"
#include "umutex.h"

#include "regexcst.h"   // Contains state table for the regex pattern parser.
                        //   generated by a Perl script.
#include "regexst.h"

U_NAMESPACE_BEGIN

// "Rule Char" Characters are those with special meaning, and therefore
//    need to be escaped to appear as literals in a regexp.
constexpr char16_t const *gRuleSet_rule_chars = u"*?+[(){}^$|\\.";

//
//   The backslash escape characters that ICU's unescape() function will handle.
//
constexpr char16_t const *gUnescapeChars = u"acefnrtuUx";

//
//  Unicode Set pattern for Regular Expression  \w
//
constexpr char16_t const *gIsWordPattern = u"[\\p{Alphabetic}\\p{M}\\p{Nd}\\p{Pc}\\u200c\\u200d]";

//
//  Unicode Set Definitions for Regular Expression  \s
//
constexpr  char16_t const *gIsSpacePattern = u"[\\p{WhiteSpace}]";

//
//  UnicodeSets used in implementation of Grapheme Cluster detection, \X
//
constexpr char16_t const *gGC_ControlPattern = u"[[:Zl:][:Zp:][:Cc:][:Cf:]-[:Grapheme_Extend:]]";
constexpr char16_t const *gGC_ExtendPattern  = u"[\\p{Grapheme_Extend}]";
constexpr char16_t const *gGC_LPattern       = u"[\\p{Hangul_Syllable_Type=L}]";
constexpr char16_t const *gGC_VPattern       = u"[\\p{Hangul_Syllable_Type=V}]";
constexpr char16_t const *gGC_TPattern       = u"[\\p{Hangul_Syllable_Type=T}]";
constexpr char16_t const *gGC_LVPattern      = u"[\\p{Hangul_Syllable_Type=LV}]";
constexpr char16_t const *gGC_LVTPattern     = u"[\\p{Hangul_Syllable_Type=LVT}]";


RegexStaticSets *RegexStaticSets::gStaticSets = nullptr;
UInitOnce gStaticSetsInitOnce = U_INITONCE_INITIALIZER;


RegexStaticSets::RegexStaticSets(UErrorCode *status) {
    // Initialize the shared static sets to their correct values.
    fUnescapeCharSet.addAll(UnicodeString(true, gUnescapeChars, -1)).freeze();
    fPropSets[URX_ISWORD_SET].applyPattern(UnicodeString(true, gIsWordPattern, -1), *status).freeze();
    fPropSets[URX_ISSPACE_SET].applyPattern(UnicodeString(true, gIsSpacePattern, -1), *status).freeze();
    fPropSets[URX_GC_EXTEND].applyPattern(UnicodeString(TRUE, gGC_ExtendPattern, -1), *status).freeze();
    fPropSets[URX_GC_CONTROL].applyPattern(UnicodeString(TRUE, gGC_ControlPattern, -1), *status).freeze();
    fPropSets[URX_GC_L].applyPattern(UnicodeString(TRUE, gGC_LPattern, -1), *status).freeze();
    fPropSets[URX_GC_V].applyPattern(UnicodeString(TRUE, gGC_VPattern, -1), *status).freeze();
    fPropSets[URX_GC_T].applyPattern(UnicodeString(TRUE, gGC_TPattern, -1), *status).freeze();
    fPropSets[URX_GC_LV].applyPattern(UnicodeString(TRUE, gGC_LVPattern, -1), *status).freeze();
    fPropSets[URX_GC_LVT].applyPattern(UnicodeString(TRUE, gGC_LVTPattern, -1), *status).freeze();
    

    //
    //  "Normal" is the set of characters that don't need special handling
    //            when finding grapheme cluster boundaries.
    //
    fPropSets[URX_GC_NORMAL].complement();
    fPropSets[URX_GC_NORMAL].remove(0xac00, 0xd7a4);
    fPropSets[URX_GC_NORMAL].removeAll(fPropSets[URX_GC_CONTROL]);
    fPropSets[URX_GC_NORMAL].removeAll(fPropSets[URX_GC_L]);
    fPropSets[URX_GC_NORMAL].removeAll(fPropSets[URX_GC_V]);
    fPropSets[URX_GC_NORMAL].removeAll(fPropSets[URX_GC_T]);
    fPropSets[URX_GC_NORMAL].freeze();

    // Initialize the 8-bit fast bit sets from the parallel full
    //   UnicodeSets.
    //
    // TODO: 25 Oct 2019 are these fast 8-bit sets worth keeping?
    //       Measured 3.5% gain on (non) matching with the pattern "x(?:\\S+)+x"
    //       This runs in exponential time, making it easy to adjust the time for
    //       convenient measuring.
    //
    //       This 8 bit optimization dates from the early days of ICU,
    //       with a less optimized UnicodeSet. At the time, the difference
    //       was substantial.

    for (int32_t i=0; i<URX_LAST_SET; i++) {
        fPropSets8[i].init(&fPropSets[i]);
    }

    // Sets used while parsing rules, but not referenced from the parse state table
    fRuleSets[kRuleSet_rule_char-128]
            .addAll(UnicodeString(gRuleSet_rule_chars)).complement().freeze();

    fRuleSets[kRuleSet_digit_char-128].add(u'0', u'9').freeze();
    fRuleSets[kRuleSet_ascii_letter-128].add(u'A', u'Z').add(u'a', u'z').freeze();
    fRuleDigitsAlias = &fRuleSets[kRuleSet_digit_char-128];
    
    // Finally, initialize an empty UText string for utility purposes
    fEmptyText = utext_openUChars(nullptr, nullptr, 0, status);
    
}


RegexStaticSets::~RegexStaticSets() {
    fRuleDigitsAlias = nullptr;
    utext_close(fEmptyText);
}


//------------------------------------------------------------------------------
//
//   regex_cleanup      Memory cleanup function, free/delete all
//                      cached memory.  Called by ICU's u_cleanup() function.
//
//------------------------------------------------------------------------------

U_CDECL_BEGIN
static UBool U_CALLCONV
regex_cleanup(void) {
    delete RegexStaticSets::gStaticSets;
    RegexStaticSets::gStaticSets = nullptr;
    gStaticSetsInitOnce.reset();
    return TRUE;
}

static void U_CALLCONV initStaticSets(UErrorCode &status) {
    U_ASSERT(RegexStaticSets::gStaticSets == nullptr);
    ucln_i18n_registerCleanup(UCLN_I18N_REGEX, regex_cleanup);
    RegexStaticSets::gStaticSets = new RegexStaticSets(&status);
    if (U_FAILURE(status)) {
        delete RegexStaticSets::gStaticSets;
        RegexStaticSets::gStaticSets = nullptr;
    }
    if (RegexStaticSets::gStaticSets == nullptr && U_SUCCESS(status)) {
        status = U_MEMORY_ALLOCATION_ERROR;
    }
}
U_CDECL_END

void RegexStaticSets::initGlobals(UErrorCode *status) {
    umtx_initOnce(gStaticSetsInitOnce, &initStaticSets, *status);
}

U_NAMESPACE_END
#endif  // !UCONFIG_NO_REGULAR_EXPRESSIONS
