  this.dataLoaded.level1.add(country);
    }
    return this.#parse(
      this.addressData[`${this.DATA_PREFIX}${country}/${level1}`]
    );
  }

  /**
   * Return the region metadata with default locale and other locales (if exists).
   *
   * @param   {string} country
   * @param   {string?} level1
   * @returns {object} Return default locale and other locales metadata.
   */
  static getData(country, level1 = null) {
    const defaultLocale = this.#loadData(country, level1);
    if (!defaultLocale) {
      return null;
    }

    const countryData = this.#parse(
      this.addressData[`${this.DATA_PREFIX}${country}`]
    );
    let locales = [];
    // TODO: Should be able to support multi-locale level 1/ level 2 metadata query
    //      in Bug 1421886
    if (countryData.languages) {
      const list = countryData.languages.filter(
        key => key !== countryData.lang
      );
      locales = list.map(key =>
        this.#parse(this.addressData[`${defaultLocale.id}--${key}`])
      );
    }
    return { defaultLocale, locales };
  }

  /**
   * Return an array containing countries alpha2 codes.
   *
   * @returns {Array} Return an array containing countries alpha2 codes.
   */
  static get #countryCodes() {
    return Object.keys(lazy.AddressMetaDataExtension).map(dataKey =>
      dataKey.replace(this.DATA_PREFIX, "")
    );
  }

  static getCountries(locales = []) {
    const displayNames = new Intl.DisplayNames(locales, {
      type: "region",
      fallback: "none",
    });
    const countriesMap = new Map();
    for (const countryCode of this.#countryCodes) {
      countriesMap.set(countryCode, displayNames.of(countryCode));
    }
    return countriesMap;
  }
}

export default AddressMetaDataLoader;
PK