// © 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

#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 {};


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
