// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/**
 *******************************************************************************
 * Copyright (C) 2001-2011, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 *******************************************************************************
 */
#ifndef ICULSERV_H
#define ICULSERV_H

#include "unicode/utypes.h"

#if UCONFIG_NO_SERVICE

U_NAMESPACE_BEGIN

/*
 * Allow the declaration of APIs with pointers to ICUService
 * even when service is removed from the build.
 */
class ICULocaleService;

U_NAMESPACE_END

#else

#include "unicode/unistr.h"
#include "unicode/locid.h"
#include "unicode/strenum.h"

#include "hash.h"
#include "uvector.h"

#include "serv.h"
#include "locutil.h"

U_NAMESPACE_BEGIN

class ICULocaleService;

class LocaleKey;
class LocaleKeyFactory;
class SimpleLocaleKeyFactory;
class ServiceListener;

/*
 ******************************************************************
 */

/**
 * A subclass of Key that implements a locale fallback mechanism.
 * The first locale to search for is the locale provided by the
 * client, and the fallback locale to search for is the current
 * default locale.  If a prefix is present, the currentDescriptor
 * includes it before the locale proper, separated by "/".  This
 * is the default key instantiated by ICULocaleService.</p>
 *
 * <p>Canonicalization adjusts the locale string so that the
 * section before the first understore is in lower case, and the rest
 * is in upper case, with no trailing underscores.</p> 
 */

class U_COMMON_API LocaleKey : public ICUServiceKey {
  private: 
    int32_t _kind;
    UnicodeString _primaryID;
    UnicodeString _fallbackID;
    UnicodeString _currentID;

  public:
    enum {
        KIND_ANY = -1
    };

    /**
     * Create a LocaleKey with canonical primary and fallback IDs.
     */
    static LocaleKey* createWithCanonicalFallback(const UnicodeString* primaryID, 
                                                  const UnicodeString* canonicalFallbackID,
                                                  UErrorCode& status);

    /**
     * Create a LocaleKey with canonical primary and fallback IDs.
     */
    static LocaleKey* createWithCanonicalFallback(const UnicodeString* primaryID, 
                                                  const UnicodeString* canonicalFallbackID, 
                                                  int32_t kind,
                                                  UErrorCode& status);

  protected:
    /**
     * PrimaryID is the user's requested locale string,
     * canonicalPrimaryID is this string in canonical form,
     * fallbackID is the current default locale's string in
     * canonical form.
     */
    LocaleKey(const UnicodeString& primaryID, 
              const UnicodeString& canonicalPrimaryID, 
              const UnicodeString* canonicalFallbackID, 
              int32_t kind);

 public:
    /**
     * Append the prefix associated with the kind, or nothing if the kind is KIND_ANY.
     */
    virtual UnicodeString& prefix(UnicodeString& result) const;

    /**
     * Return the kind code associated with this key.
     */
    virtual int32_t kind() const;

    /**
     * Return the canonicalID.
     */
    virtual UnicodeString& canonicalID(UnicodeString& result) const;

    /**
     * Return the currentID.
     */
    virtual UnicodeString& currentID(UnicodeString& result) const;

    /**
     * Return the (canonical) current descriptor, or null if no current id.
     */
    virtual UnicodeString& currentDescriptor(UnicodeString& result) const;

    /**
     * Convenience method to return the locale corresponding to the (canonical) original ID.
     */
    virtual Locale& canonicalLocale(Locale& result) const;

    /**
     * Convenience method to return the locale corresponding to the (canonical) current ID.
     */
    virtual Locale& currentLocale(Locale& result) const;

    /**
     * If the key has a fallback, modify the key and return true,
     * otherwise return false.</p>
     *
     * <p>First falls back through the primary ID, then through
     * the fallbackID.  The final fallback is the empty string,
     * unless the primary id was the empty string, in which case
     * there is no fallback.  
     */
    virtual UBool fallback();

    /**
     * Return true if a key created from id matches, or would eventually
     * fallback to match, the canonical ID of this key.  
     */
    virtual UBool isFallbackOf(const UnicodeString& id) const;
    
 public:
    /**
     * UObject boilerplate.
     */
    static UClassID U_EXPORT2 getStaticClassID();

    virtual UClassID getDynamicClassID() const;

    /**
     * Destructor.
     */
    virtual ~LocaleKey();

#ifdef SERVICE_DEBUG
 public:
    virtual UnicodeString& debug(UnicodeString& result) const;
    virtual UnicodeString& debugClass(UnicodeString& result) const;
#endif

};

/*
 ******************************************************************
 */

/**
 * A subclass of ICUServiceFactory that uses LocaleKeys, and is able to
 * 'cover' more specific locales with more general locales that it
 * supports.  
 *
 * <p>Coverage may be either of the values VISIBLE or INVISIBLE.
 *
 * <p>'Visible' indicates that the specific locale(s) supported by
 * the factory are registered in getSupportedIDs, 'Invisible'
 * indicates that they are not.
 *
 * <p>Localization of visible ids is handled
 * by the handling factory, regardless of kind.
 */
class U_COMMON_API LocaleKeyFactory : public ICUServiceFactory {
protected:
    const UnicodeString _name;
    const int32_t _coverage;

public:
    enum {
        /**
         * Coverage value indicating that the factory makes
         * its locales visible, and does not cover more specific 
         * locales.
         */
        VISIBLE = 0,

        /**
         * Coverage value indicating that the factory does not make
         * its locales visible, and does not cover more specific
         * locales.
         */
        INVISIBLE = 1
    };

    /**
     * Destructor.
     */
    virtual ~LocaleKeyFactory();

protected:
    /**
     * Constructor used by subclasses.
     */
    LocaleKeyFactory(int32_t coverage);

    /**
     * Constructor used by subclasses.
     */
    LocaleKeyFactory(int32_t coverage, const UnicodeString& name);

    /**
     * Implement superclass abstract method.  This checks the currentID of
     * the key against the supported IDs, and passes the canonicalLocale and
     * kind off to handleCreate (which subclasses must implement).
     */
public:
    virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;

protected:
    virtual UBool handlesKey(const ICUServiceKey& key, UErrorCode& status) const;

public:
    /**
     * Override of superclass method.  This adjusts the result based
     * on the coverage rule for this factory.
     */
    virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const;

    /**
     * Return a localized name for the locale represented by id.
     */
    virtual UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const;

protected:
    /**
     * Utility method used by create(ICUServiceKey, ICUService).  Subclasses can implement
     * this instead of create.  The default returns NULL.
     */
    virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* service, UErrorCode& status) const;

   /**
     * Return true if this id is one the factory supports (visible or 
     * otherwise).
     */
 //   virtual UBool isSupportedID(const UnicodeString& id, UErrorCode& status) const;

   /**
     * Return the set of ids that this factory supports (visible or 
     * otherwise).  This can be called often and might need to be
     * cached if it is expensive to create.
     */
    virtual const Hashtable* getSupportedIDs(UErrorCode& status) const;

public:
    /**
     * UObject boilerplate.
     */
    static UClassID U_EXPORT2 getStaticClassID();

    virtual UClassID getDynamicClassID() const;

#ifdef SERVICE_DEBUG
 public:
    virtual UnicodeString& debug(UnicodeString& result) const;
    virtual UnicodeString& debugClass(UnicodeString& result) const;
#endif

};

/*
 ******************************************************************
 */

/**
 * A LocaleKeyFactory that just returns a single object for a kind/locale.
 */

class U_COMMON_API SimpleLocaleKeyFactory : public LocaleKeyFactory {
 private:
    UObject* _obj;
    UnicodeString _id;
    const int32_t _kind;

 public:
    SimpleLocaleKeyFactory(UObject* objToAdopt, 
                           const UnicodeString& locale, 
                           int32_t kind, 
                           int32_t coverage);

    SimpleLocaleKeyFactory(UObject* objToAdopt, 
                           const Locale& locale, 
                           int32_t kind, 
                           int32_t coverage);

    /**
     * Destructor.
     */
    virtual ~SimpleLocaleKeyFactory();

    /**
     * Override of superclass method.  Returns the service object if kind/locale match.  Service is not used.
     */
    virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;

    /**
     * Override of superclass method.  This adjusts the result based
     * on the coverage rule for this factory.
     */
    virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const;

 protected:
    /**
     * Return true if this id is equal to the locale name.
     */
    //virtual UBool isSupportedID(const UnicodeString& id, UErrorCode& status) const;


public:
    /**
     * UObject boilerplate.
     */
    static UClassID U_EXPORT2 getStaticClassID();

    virtual UClassID getDynamicClassID() const;

#ifdef SERVICE_DEBUG
 public:
    virtual UnicodeString& debug(UnicodeString& result) const;
    virtual UnicodeString& debugClass(UnicodeString& result) const;
#endif

};

/*
 ******************************************************************
 */

/**
 * A LocaleKeyFactory that creates a service based on the ICU locale data.
 * This is a base class for most ICU factories.  Subclasses instantiate it
 * with a constructor that takes a bundle name, which determines the supported
 * IDs.  Subclasses then override handleCreate to create the actual service
 * object.  The default implementation returns a resource bundle.
 */
class U_COMMON_API ICUResourceBundleFactory : public LocaleKeyFactory 
{
 protected:
    UnicodeString _bundleName;

 public:
    /**
     * Convenience constructor that uses the main ICU bundle name.
     */
    ICUResourceBundleFactory();

    /**
     * A service factory based on ICU resource data in resources with
     * the given name.  This should be a 'path' that can be passed to
     * ures_openAvailableLocales, such as U_ICUDATA or U_ICUDATA_COLL.
     * The empty string is equivalent to U_ICUDATA.
     */
    ICUResourceBundleFactory(const UnicodeString& bundleName);

    /**
     * Destructor
     */
    virtual ~ICUResourceBundleFactory();

protected:
    /**
     * Return the supported IDs.  This is the set of all locale names in ICULocaleData.
     */
    virtual const Hashtable* getSupportedIDs(UErrorCode& status) const;

    /**
     * Create the service.  The default implementation returns the resource bundle
     * for the locale, ignoring kind, and service.
     */
    virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* service, UErrorCode& status) const;

public:
    /**
     * UObject boilerplate.
     */
    static UClassID U_EXPORT2 getStaticClassID();
    virtual UClassID getDynamicClassID() const;


#ifdef SERVICE_DEBUG
 public:
    virtual UnicodeString& debug(UnicodeString& result) const;
    virtual UnicodeString& debugClass(UnicodeString& result) const;
#endif

};

/*
 ******************************************************************
 */

class U_COMMON_API ICULocaleService : public ICUService 
{
 private:
  Locale fallbackLocale;
  UnicodeString fallbackLocaleName;

 public:
  /**
   * Construct an ICULocaleService.
   */
  ICULocaleService();

  /**
   * Construct an ICULocaleService with a name (useful for debugging).
   */
  ICULocaleService(const UnicodeString& name);

  /**
   * Destructor.
   */
  virtual ~ICULocaleService();

#if 0
  // redeclare because of overload resolution rules?
  // no, causes ambiguities since both UnicodeString and Locale have constructors that take a const char*
  // need some compiler flag to remove warnings 
  UObject* get(const UnicodeString& descriptor, UErrorCode& status) const {
    return ICUService::get(descriptor, status);
  }

  UObject* get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const {
    return ICUService::get(descriptor, actualReturn, status);
  }
#endif

  /**
   * Convenience override for callers using locales.  This calls
   * get(Locale, int, Locale[]) with KIND_ANY for kind and null for
   * actualReturn.
   */
  UObject* get(const Locale& locale, UErrorCode& status) const;

  /**
   * Convenience override for callers using locales.  This calls
   * get(Locale, int, Locale[]) with a null actualReturn.
   */
  UObject* get(const Locale& locale, int32_t kind, UErrorCode& status) const;

  /**
   * Convenience override for callers using locales. This calls
   * get(Locale, String, Locale[]) with a null kind.
   */
  UObject* get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const;
                   
  /**
   * Convenience override for callers using locales.  This uses
   * createKey(Locale.toString(), kind) to create a key, calls getKey, and then
   * if actualReturn is not null, returns the actualResult from
   * getKey (stripping any prefix) into a Locale.  
   */
  UObject* get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const;

  /**
   * Convenience override for callers using locales.  This calls
   * registerObject(Object, Locale, int32_t kind, int coverage)
   * passing KIND_ANY for the kind, and VISIBLE for the coverage.
   */
  virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status);

  /**
   * Convenience function for callers using locales.  This calls
   * registerObject(Object, Locale, int kind, int coverage)
   * passing VISIBLE for the coverage.
   */
  virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status);

  /**
   * Convenience function for callers using locales.  This  instantiates
   * a SimpleLocaleKeyFactory, and registers the factory.
   */
  virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status);


  /**
   * (Stop compiler from complaining about hidden overrides.)
   * Since both UnicodeString and Locale have constructors that take const char*, adding a public
   * method that takes UnicodeString causes ambiguity at call sites that use const char*.
   * We really need a flag that is understood by all compilers that will suppress the warning about
   * hidden overrides.
   */
  virtual URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status);

  /**
   * Convenience method for callers using locales.  This returns the standard
   * service ID enumeration.
   */
  virtual StringEnumeration* getAvailableLocales(void) const;

 protected:

  /**
   * Return the name of the current fallback locale.  If it has changed since this was
   * last accessed, the service cache is cleared.
   */
  const UnicodeString& validateFallbackLocale() const;

  /**
   * Override superclass createKey method.
   */
  virtual ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const;

  /**
   * Additional createKey that takes a kind.
   */
  virtual ICUServiceKey* createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const;

  friend class ServiceEnumeration;
};

U_NAMESPACE_END

    /* UCONFIG_NO_SERVICE */
#endif

    /* ICULSERV_H */
#endif

