// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

// Allow implicit conversion from char16_t* to UnicodeString for this file:
// Helpful in toString methods and elsewhere.
#define UNISTR_FROM_STRING_EXPLICIT

#include "numparse_types.h"
#include "numparse_compositions.h"
#include "unicode/uniset.h"

using namespace icu;
using namespace icu::numparse;
using namespace icu::numparse::impl;


bool SeriesMatcher::match(StringSegment& segment, ParsedNumber& result, UErrorCode& status) const {
    ParsedNumber backup(result);

    int32_t initialOffset = segment.getOffset();
    bool maybeMore = true;
    for (auto* it = begin(); it < end();) {
        const NumberParseMatcher* matcher = *it;
        int matcherOffset = segment.getOffset();
        if (segment.length() != 0) {
            maybeMore = matcher->match(segment, result, status);
        } else {
            // Nothing for this matcher to match; ask for more.
            maybeMore = true;
        }

        bool success = (segment.getOffset() != matcherOffset);
        bool isFlexible = matcher->isFlexible();
        if (success && isFlexible) {
            // Match succeeded, and this is a flexible matcher. Re-run it.
        } else if (success) {
            // Match succeeded, and this is NOT a flexible matcher. Proceed to the next matcher.
            it++;
            // Small hack: if there is another matcher coming, do not accept trailing weak chars.
            // Needed for proper handling of currency spacing.
            if (it < end() && segment.getOffset() != result.charEnd && result.charEnd > matcherOffset) {
                segment.setOffset(result.charEnd);
            }
        } else if (isFlexible) {
            // Match failed, and this is a flexible matcher. Try again with the next matcher.
            it++;
        } else {
            // Match failed, and this is NOT a flexible matcher. Exit.
            segment.setOffset(initialOffset);
            result = backup;
            return maybeMore;
        }
    }

    // All matchers in the series succeeded.
    return maybeMore;
}

bool SeriesMatcher::smokeTest(const StringSegment& segment) const {
    // NOTE: The range-based for loop calls the virtual begin() and end() methods.
    // NOTE: We only want the first element. Use the for loop for boundary checking.
    for (auto& matcher : *this) {
        // SeriesMatchers are never allowed to start with a Flexible matcher.
        U_ASSERT(!matcher->isFlexible());
        return matcher->smokeTest(segment);
    }
    return false;
}

void SeriesMatcher::postProcess(ParsedNumber& result) const {
    // NOTE: The range-based for loop calls the virtual begin() and end() methods.
    for (auto* matcher : *this) {
        matcher->postProcess(result);
    }
}


ArraySeriesMatcher::ArraySeriesMatcher()
        : fMatchersLen(0) {
}

ArraySeriesMatcher::ArraySeriesMatcher(MatcherArray& matchers, int32_t matchersLen)
        : fMatchers(std::move(matchers)), fMatchersLen(matchersLen) {
}

int32_t ArraySeriesMatcher::length() const {
    return fMatchersLen;
}

const NumberParseMatcher* const* ArraySeriesMatcher::begin() const {
    return fMatchers.getAlias();
}

const NumberParseMatcher* const* ArraySeriesMatcher::end() const {
    return fMatchers.getAlias() + fMatchersLen;
}

UnicodeString ArraySeriesMatcher::toString() const {
    return u"<ArraySeries>";
}


#endif /* #if !UCONFIG_NO_FORMATTING */
