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