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

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING
#ifndef __NUMBER_MODIFIERS_H__
#define __NUMBER_MODIFIERS_H__

#include <algorithm>
#include <cstdint>
#include "unicode/uniset.h"
#include "unicode/simpleformatter.h"
#include "standardplural.h"
#include "formatted_string_builder.h"
#include "number_types.h"

U_NAMESPACE_BEGIN namespace number {
namespace impl {

/**
 * The canonical implementation of {@link Modifier}, containing a prefix and suffix string.
 * TODO: This is not currently being used by real code and could be removed.
 */
class U_I18N_API ConstantAffixModifier : public Modifier, public UObject {
  public:
    ConstantAffixModifier(const UnicodeString &prefix, const UnicodeString &suffix, Field field,
                          bool strong)
            : fPrefix(prefix), fSuffix(suffix), fField(field), fStrong(strong) {}

    int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
                  UErrorCode &status) const U_OVERRIDE;

    int32_t getPrefixLength() const U_OVERRIDE;

    int32_t getCodePointCount() const U_OVERRIDE;

    bool isStrong() const U_OVERRIDE;

    bool containsField(Field field) const U_OVERRIDE;

    void getParameters(Parameters& output) const U_OVERRIDE;

    bool semanticallyEquivalent(const Modifier& other) const U_OVERRIDE;

  private:
    UnicodeString fPrefix;
    UnicodeString fSuffix;
    Field fField;
    bool fStrong;
};

/**
 * The second primary implementation of {@link Modifier}, this one consuming a {@link SimpleFormatter}
 * pattern.
 */
class U_I18N_API SimpleModifier : public Modifier, public UMemory {
  public:
    SimpleModifier(const SimpleFormatter &simpleFormatter, Field field, bool strong);

    SimpleModifier(const SimpleFormatter &simpleFormatter, Field field, bool strong,
                   const Modifier::Parameters parameters);

    // Default constructor for LongNameHandler.h
    SimpleModifier();

    int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
                  UErrorCode &status) const U_OVERRIDE;

    int32_t getPrefixLength() const U_OVERRIDE;

    int32_t getCodePointCount() const U_OVERRIDE;

    bool isStrong() const U_OVERRIDE;

    bool containsField(Field field) const U_OVERRIDE;

    void getParameters(Parameters& output) const U_OVERRIDE;

    bool semanticallyEquivalent(const Modifier& other) const U_OVERRIDE;

    /**
     * TODO: This belongs in SimpleFormatterImpl. The only reason I haven't moved it there yet is because
     * FormattedStringBuilder is an internal class and SimpleFormatterImpl feels like it should not depend on it.
     *
     * <p>
     * Formats a value that is already stored inside the StringBuilder <code>result</code> between the indices
     * <code>startIndex</code> and <code>endIndex</code> by inserting characters before the start index and after the
     * end index.
     *
     * <p>
     * This is well-defined only for patterns with exactly one argument.
     *
     * @param result
     *            The StringBuilder containing the value argument.
     * @param startIndex
     *            The left index of the value within the string builder.
     * @param endIndex
     *            The right index of the value within the string builder.
     * @return The number of characters (UTF-16 code points) that were added to the StringBuilder.
     */
    int32_t
    formatAsPrefixSuffix(FormattedStringBuilder& result, int32_t startIndex, int32_t endIndex,
                         UErrorCode& status) const;

    /**
     * TODO: Like above, this belongs with the rest of the SimpleFormatterImpl code.
     * I put it here so that the SimpleFormatter uses in FormattedStringBuilder are near each other.
     *
     * <p>
     * Applies the compiled two-argument pattern to the FormattedStringBuilder.
     *
     * <p>
     * This method is optimized for the case where the prefix and suffix are often empty, such as
     * in the range pattern like "{0}-{1}".
     */
    static int32_t
    formatTwoArgPattern(const SimpleFormatter& compiled, FormattedStringBuilder& result,
                        int32_t index, int32_t* outPrefixLength, int32_t* outSuffixLength,
                        Field field, UErrorCode& status);

  private:
    UnicodeString fCompiledPattern;
    Field fField;
    bool fStrong = false;
    int32_t fPrefixLength = 0;
    int32_t fSuffixOffset = -1;
    int32_t fSuffixLength = 0;
    Modifier::Parameters fParameters;
};

/**
 * An implementation of {@link Modifier} that allows for multiple types of fields in the same modifier. Constructed
 * based on the contents of two {@link FormattedStringBuilder} instances (one for the prefix, one for the suffix).
 */
class U_I18N_API ConstantMultiFieldModifier : public Modifier, public UMemory {
  public:
    ConstantMultiFieldModifier(
            const FormattedStringBuilder &prefix,
            const FormattedStringBuilder &suffix,
            bool overwrite,
            bool strong,
            const Modifier::Parameters parameters)
      : fPrefix(prefix),
        fSuffix(suffix),
        fOverwrite(overwrite),
        fStrong(strong),
        fParameters(parameters) {}

    ConstantMultiFieldModifier(
            const FormattedStringBuilder &prefix,
            const FormattedStringBuilder &suffix,
            bool overwrite,
            bool strong)
      : fPrefix(prefix),
        fSuffix(suffix),
        fOverwrite(overwrite),
        fStrong(strong) {}

    int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
                  UErrorCode &status) const U_OVERRIDE;

    int32_t getPrefixLength() const U_OVERRIDE;

    int32_t getCodePointCount() const U_OVERRIDE;

    bool isStrong() const U_OVERRIDE;

    bool containsField(Field field) const U_OVERRIDE;

    void getParameters(Parameters& output) const U_OVERRIDE;

    bool semanticallyEquivalent(const Modifier& other) const U_OVERRIDE;

  protected:
    // NOTE: In Java, these are stored as array pointers. In C++, the FormattedStringBuilder is stored by
    // value and is treated internally as immutable.
    FormattedStringBuilder fPrefix;
    FormattedStringBuilder fSuffix;
    bool fOverwrite;
    bool fStrong;
    Modifier::Parameters fParameters;
};

/** Identical to {@link ConstantMultiFieldModifier}, but supports currency spacing. */
class U_I18N_API CurrencySpacingEnabledModifier : public ConstantMultiFieldModifier {
  public:
    /** Safe code path */
    CurrencySpacingEnabledModifier(
            const FormattedStringBuilder &prefix,
            const FormattedStringBuilder &suffix,
            bool overwrite,
            bool strong,
            const DecimalFormatSymbols &symbols,
            UErrorCode &status);

    int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
                  UErrorCode &status) const U_OVERRIDE;

    /** Unsafe code path */
    static int32_t
    applyCurrencySpacing(FormattedStringBuilder &output, int32_t prefixStart, int32_t prefixLen,
                         int32_t suffixStart, int32_t suffixLen, const DecimalFormatSymbols &symbols,
                         UErrorCode &status);

  private:
    UnicodeSet fAfterPrefixUnicodeSet;
    UnicodeString fAfterPrefixInsert;
    UnicodeSet fBeforeSuffixUnicodeSet;
    UnicodeString fBeforeSuffixInsert;

    enum EAffix {
        PREFIX, SUFFIX
    };

    enum EPosition {
        IN_CURRENCY, IN_NUMBER
    };

    /** Unsafe code path */
    static int32_t applyCurrencySpacingAffix(FormattedStringBuilder &output, int32_t index, EAffix affix,
                                             const DecimalFormatSymbols &symbols, UErrorCode &status);

    static UnicodeSet
    getUnicodeSet(const DecimalFormatSymbols &symbols, EPosition position, EAffix affix,
                  UErrorCode &status);

    static UnicodeString
    getInsertString(const DecimalFormatSymbols &symbols, EAffix affix, UErrorCode &status);
};

/** A Modifier that does not do anything. */
class U_I18N_API EmptyModifier : public Modifier, public UMemory {
  public:
    explicit EmptyModifier(bool isStrong) : fStrong(isStrong) {}

    int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
                  UErrorCode &status) const U_OVERRIDE {
        (void)output;
        (void)leftIndex;
        (void)rightIndex;
        (void)status;
        return 0;
    }

    int32_t getPrefixLength() const U_OVERRIDE {
        return 0;
    }

    int32_t getCodePointCount() const U_OVERRIDE {
        return 0;
    }

    bool isStrong() const U_OVERRIDE {
        return fStrong;
    }

    bool containsField(Field field) const U_OVERRIDE {
        (void)field;
        return false;
    }

    void getParameters(Parameters& output) const U_OVERRIDE {
        output.obj = nullptr;
    }

    bool semanticallyEquivalent(const Modifier& other) const U_OVERRIDE {
        return other.getCodePointCount() == 0;
    }

  private:
    bool fStrong;
};

/**
 * This implementation of ModifierStore adopts Modifer pointers.
 */
class U_I18N_API AdoptingModifierStore : public ModifierStore, public UMemory {
  public:
    virtual ~AdoptingModifierStore();

    static constexpr StandardPlural::Form DEFAULT_STANDARD_PLURAL = StandardPlural::OTHER;

    AdoptingModifierStore() = default;

    // No copying!
    AdoptingModifierStore(const AdoptingModifierStore &other) = delete;

    /**
     * Sets the Modifier with the specified signum and plural form.
     */
    void adoptModifier(Signum signum, StandardPlural::Form plural, const Modifier *mod) {
        U_ASSERT(mods[getModIndex(signum, plural)] == nullptr);
        mods[getModIndex(signum, plural)] = mod;
    }

    /**
     * Sets the Modifier with the specified signum.
     * The modifier will apply to all plural forms.
     */
    void adoptModifierWithoutPlural(Signum signum, const Modifier *mod) {
        U_ASSERT(mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)] == nullptr);
        mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)] = mod;
    }

    /** Returns a reference to the modifier; no ownership change. */
    const Modifier *getModifier(Signum signum, StandardPlural::Form plural) const U_OVERRIDE {
        const Modifier* modifier = mods[getModIndex(signum, plural)];
        if (modifier == nullptr && plural != DEFAULT_STANDARD_PLURAL) {
            modifier = mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)];
        }
        return modifier;
    }

    /** Returns a reference to the modifier; no ownership change. */
    const Modifier *getModifierWithoutPlural(Signum signum) const {
        return mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)];
    }

  private:
    // NOTE: mods is zero-initialized (to nullptr)
    const Modifier *mods[4 * StandardPlural::COUNT] = {};

    inline static int32_t getModIndex(Signum signum, StandardPlural::Form plural) {
        U_ASSERT(signum >= 0 && signum < SIGNUM_COUNT);
        U_ASSERT(plural >= 0 && plural < StandardPlural::COUNT);
        return static_cast<int32_t>(plural) * SIGNUM_COUNT + signum;
    }
};

} // namespace impl
} // namespace number
U_NAMESPACE_END


#endif //__NUMBER_MODIFIERS_H__

#endif /* #if !UCONFIG_NO_FORMATTING */
