content: package com.alphawallet.app.repository;
  
  import android.annotation.SuppressLint;
  import android.content.Context;
  import android.content.SharedPreferences;
  
  import androidx.annotation.NonNull;
  import androidx.preference.PreferenceManager;
  
  import com.alphawallet.app.C;
  import com.alphawallet.app.entity.CurrencyItem;
  
  import java.util.HashSet;
  import java.util.Locale;
  import java.util.Set;
  
  public class SharedPreferenceRepository implements PreferenceRepositoryType {
      private static final String CURRENT_ACCOUNT_ADDRESS_KEY = "current_account_address";
      private static final String DEFAULT_NETWORK_NAME_KEY = "default_network_name";
      private static final String NETWORK_FILTER_KEY = "network_filters";
      private static final String CUSTOM_NETWORKS_KEY = "custom_networks";
      private static final String TRANSACTION_NOTIFICATIONS_ENABLED = "transaction_notifications_enabled_";
      private static final String POST_NOTIFICATIONS_PERMISSION_REQUESTED = "post_notifications_permission_requested_";
      private static final String THEME_KEY = "theme";
      private static final String DEFAULT_SET_KEY = "default_net_set";
      private static final String LOCALE_KEY = "locale";
      private static final String BACKUP_WALLET_SHOWN = "backup_wallet_shown";
      private static final String FIND_WALLET_ADDRESS_SHOWN = "find_wallet_address_shown";
      public static final String CURRENCY_CODE_KEY = "currency_locale";
      public static final String CURRENCY_SYMBOL_KEY = "currency_symbol";
      public static final String USER_LOCALE_PREF = "user_locale_pref";
      public static final String HIDE_ZERO_BALANCE_TOKENS = "hide_zero_balance_tokens";
      public static final String FULL_SCREEN_STATE = "full_screen";
      public static final String EXPERIMENTAL_1559_TX = "ex_1559_tx";
      public static final String USE_TOKENSCRIPT_VIEWER = "use_ts_viewer";
      public static final String DEVELOPER_OVERRIDE = "developer_override";
      public static final String TESTNET_ENABLED = "testnet_enabled";
      public static final String PRICE_ALERTS = "price_alerts";
      private static final String SET_NETWORK_FILTERS = "set_filters";
      private static final String SHOULD_SHOW_ROOT_WARNING = "should_show_root_warning";
      private static final String UPDATE_WARNINGS = "update_warns";
      private static final String INSTALL_TIME = "install_time";
      public static final String DEVICE_LOCALE = "device_locale";
      public static final String DEVICE_COUNTRY = "device_country";
      public static final String MARSHMALLOW_SUPPORT_WARNING = "marshmallow_version_support_warning_shown";
      private static final String LAST_FRAGMENT_ID = "lastfrag_id";
      private static final String LAST_VERSION_CODE = "last_version_code";
      private static final String SELECTED_SWAP_PROVIDERS_KEY = "selected_exchanges";
      private static final String ANALYTICS_KEY = "analytics_key";
      private static final String CRASH_REPORTING_KEY = "crash_reporting_key";
      private static final String WALLET_LOGIN_TIME = "wallet_login_time_";
      private static final String FIREBASE_MESSAGING_TOKEN = "firebase_messaging_token";
      private static final String RATE_APP_SHOWN = "rate_us_shown";
      private static final String LAUNCH_COUNT = "launch_count";
      private static final String NEW_WALLET = "new_wallet_";
      private static final String WATCH_ONLY = "watch_only";
  
      private final SharedPreferences pref;
  
      public SharedPreferenceRepository(Context context) {
          pref = PreferenceManager.getDefaultSharedPreferences(context);
      }
  
      @Override
      public String getCurrentWalletAddress() {
          return pref.getString(CURRENT_ACCOUNT_ADDRESS_KEY, null);
      }
  
      @SuppressLint("ApplySharedPref")
      @Override
      public void setCurrentWalletAddress(String address) {
          pref.edit().putString(CURRENT_ACCOUNT_ADDRESS_KEY, address).commit(); //use commit as the value may be used immediately
      }
  
      @SuppressLint("ApplySharedPref")
      @Override
      public long getActiveBrowserNetwork() {
          long selectedNetwork;
          try
          {
              selectedNetwork = pref.getLong(DEFAULT_NETWORK_NAME_KEY, 0);
          }
          catch (ClassCastException e) //previously we used Integer or String
          {
              try
              {
                  selectedNetwork = pref.getInt(DEFAULT_NETWORK_NAME_KEY, 0);
              }
              catch (ClassCastException string)
              {
                  selectedNetwork = EthereumNetworkRepository.getNetworkIdFromName(pref.getString(DEFAULT_NETWORK_NAME_KEY, ""));
              }
              pref.edit().putLong(DEFAULT_NETWORK_NAME_KEY, selectedNetwork).commit(); //commit as we need to update this immediately
          }
  
          return selectedNetwork;
      }
  
      @Override
      public void setActiveBrowserNetwork(long networkId) {
          pref.edit().putLong(DEFAULT_NETWORK_NAME_KEY, networkId).apply();
      }
  
      @Override
      public String getCustomRPCNetworks() {
          return pref.getString(CUSTOM_NETWORKS_KEY, "");
      }
  
      @Override
      public void setCustomRPCNetworks(String networks) {
          pref.edit().putString(CUSTOM_NETWORKS_KEY, networks).apply();
      }
  
      @Override
      public void setNetworkFilterList(String filters)
      {
          pref.edit().putString(NETWORK_FILTER_KEY, filters).apply();
      }
  
      @Override
      public String getNetworkFilterList()
      {
          return pref.getString(NETWORK_FILTER_KEY, "");
      }
  
      @Override
      public String getDefaultLocale() {
          return pref.getString(LOCALE_KEY, Locale.getDefault().getLanguage());
      }
  
      @Override
      public boolean isFindWalletAddressDialogShown() {
          return pref.getBoolean(FIND_WALLET_ADDRESS_SHOWN, false);
      }
  
      @Override
      public void setFindWalletAddressDialogShown(boolean isShown) {
          pref.edit().putBoolean(FIND_WALLET_ADDRESS_SHOWN, isShown).apply();
      }
  
      @Override
      public void setDefaultCurrency(CurrencyItem currencyItem) {
          if (currencyItem == null) return;
          pref.edit().putString(CURRENCY_CODE_KEY, currencyItem.getCode()).apply();
          pref.edit().putString(CURRENCY_SYMBOL_KEY, currencyItem.getSymbol()).apply();
      }
  
      @Override
      public String getDefaultCurrency() {
          return pref.getString(CURRENCY_CODE_KEY, C.DEFAULT_CURRENCY_CODE);
      }
  
      @Override
      public String getDefaultCurrencySymbol() {
          return pref.getString(CURRENCY_SYMBOL_KEY, C.DEFAULT_CURRENCY_CODE);
      }
  
      @Override
      public String getUserPreferenceLocale()
      {
          return pref.getString(USER_LOCALE_PREF, "");
      }
  
      @Override
      public void setUserPreferenceLocale(String locale)
      {
          pref.edit().putString(USER_LOCALE_PREF, locale).apply();
      }
  
      @Override
      public void setFullScreenState(boolean state)
      {
          pref.edit().putBoolean(FULL_SCREEN_STATE, state).apply();
      }
  
  
      @Override
      public boolean getFullScreenState()
      {
          return pref.getBoolean(FULL_SCREEN_STATE, false);
      }
  
      @Override
      public void setUse1559Transactions(boolean state)
      {
          pref.edit().putBoolean(EXPERIMENTAL_1559_TX, state).apply();
      }
  
      @Override
      public boolean getDeveloperOverride()
      {
          return pref.getBoolean(DEVELOPER_OVERRIDE, false);
      }
  
      @Override
      public void setDeveloperOverride(boolean state)
      {
          pref.edit().putBoolean(DEVELOPER_OVERRIDE, state).apply();
      }
  
      @Override
      public boolean isTestnetEnabled()
      {
          return pref.getBoolean(TESTNET_ENABLED, false);
      }
  
      @Override
      public void setTestnetEnabled(boolean enabled)
      {
          pref.edit().putBoolean(TESTNET_ENABLED, enabled).apply();
      }
  
      @Override
      public boolean getUse1559Transactions()
      {
          return pref.getBoolean(EXPERIMENTAL_1559_TX, true);
      }
  
      @Override
      public void setPriceAlerts(String json)
      {
          pref.edit().putString(PRICE_ALERTS, json).apply();
      }
  
      @Override
      public String getPriceAlerts()
      {
          return pref.getString(PRICE_ALERTS, "");
      }
  
      public void setHasSetNetworkFilters()
      {
          pref.edit().putBoolean(SET_NETWORK_FILTERS, true).apply();
      }
  
      @Override
      public boolean hasSetNetworkFilters()
      {
          return pref.getBoolean(SET_NETWORK_FILTERS, false);
      }
  
      @Override
      public void blankHasSetNetworkFilters()
      {
          pref.edit().putBoolean(SET_NETWORK_FILTERS, false).apply();
      }
  
      //Ensure settings are committed
      @SuppressLint("ApplySharedPref")
      @Override
      public void commit()
      {
          pref.edit().commit();
      }
  
      @Override
      public void incrementLaunchCount() {
          int prevLaunchCount = getLaunchCount();
          pref.edit().putInt(LAUNCH_COUNT, prevLaunchCount + 1).apply();
      }
  
      @Override
      public void resetLaunchCount() {
          pref.edit().putInt(LAUNCH_COUNT, 0).apply();
      }
  
      @Override
      public int getLaunchCount() {
          return pref.getInt(LAUNCH_COUNT, 0);
      }
  
      @Override
      public void setRateAppShown() {
          pref.edit().putBoolean(RATE_APP_SHOWN, true).apply();
      }
  
      @Override
      public boolean getRateAppShown() {
          return pref.getBoolean(RATE_APP_SHOWN, false);
      }
  
      @Override
      public boolean shouldShowZeroBalanceTokens() {
          return pref.getBoolean(HIDE_ZERO_BALANCE_TOKENS, false);
      }
  
      @Override
      public void setShowZeroBalanceTokens(boolean shouldShow) {
          pref.edit().putBoolean(HIDE_ZERO_BALANCE_TOKENS, shouldShow).apply();
      }
  
      @Override
      public int getUpdateWarningCount() {
          return pref.getInt(UPDATE_WARNINGS, 0);
      }
  
      @Override
      public void setUpdateWarningCount(int count) {
          pref.edit().putInt(UPDATE_WARNINGS, count).apply();
      }
  
      @Override
      public void setInstallTime(long time) {
          pref.edit().putLong(INSTALL_TIME, time).apply();
      }
  
      @Override
      public long getInstallTime() {
          return pref.getLong(INSTALL_TIME, 0);
      }
  
      @Override
      public String getUniqueId() {
          return pref.getString(C.PREF_UNIQUE_ID, "");
      }
  
      @Override
      public void setUniqueId(String uuid) {
          pref.edit().putString(C.PREF_UNIQUE_ID, uuid).apply();
      }
  
      @Override
      public boolean isMarshMallowWarningShown() {
          return pref.getBoolean(MARSHMALLOW_SUPPORT_WARNING, false);
      }
  
      @Override
      public void setMarshMallowWarning(boolean shown) {
          pref.edit().putBoolean(MARSHMALLOW_SUPPORT_WARNING, true).apply();
      }
  
      @Override
      public void storeLastFragmentPage(int ordinal)
      {
          pref.edit().putInt(LAST_FRAGMENT_ID, ordinal).apply();
      }
  
      @Override
      public int getLastFragmentPage()
      {
          return pref.getInt(LAST_FRAGMENT_ID, -1);
      }
  
      @Override
      public int getLastVersionCode(int currentCode) {
          int versionCode = pref.getInt(LAST_VERSION_CODE, 0);
          if (versionCode == 0)
          {
              setLastVersionCode(currentCode);
              versionCode = Integer.MAX_VALUE;
          }
          return versionCode; // First time users won't see the 'what's new' since the app is new, only start to see these on first update
      }
  
      @Override
      public void setLastVersionCode(int code) {
          pref.edit().putInt(LAST_VERSION_CODE, code).apply();
      }
  
      @Override
      public int getTheme()
      {
          return pref.getInt(THEME_KEY, C.THEME_AUTO);
      }
  
      @Override
      public void setTheme(int state)
      {
          pref.edit().putInt(THEME_KEY, state).apply();
      }
  
      @Override
      public boolean isNewWallet(String address)
      {
          return pref.getBoolean(getAddressKey(NEW_WALLET, address), false);
      }
  
      @Override
      public void setNewWallet(String address, boolean isNewWallet)
      {
          pref.edit().putBoolean(getAddressKey(NEW_WALLET, address), isNewWallet).apply();
      }
  
      @Override
      public boolean isWatchOnly()
      {
          return pref.getBoolean(WATCH_ONLY, false);
      }
  
      @Override
      public void setWatchOnly(boolean watchOnly)
      {
          pref.edit().putBoolean(WATCH_ONLY, watchOnly).apply();
      }
  
      @Override
      public Set<String> getSelectedSwapProviders()
      {
          return pref.getStringSet(SELECTED_SWAP_PROVIDERS_KEY, new HashSet<>());
      }
  
      @Override
      public void setSelectedSwapProviders(Set<String> swapProviders)
      {
          pref.edit().putStringSet(SELECTED_SWAP_PROVIDERS_KEY, swapProviders).apply();
      }
  
      @Override
      public boolean isAnalyticsEnabled()
      {
          return pref.getBoolean(ANALYTICS_KEY, true);
      }
  
      @Override
      public void setAnalyticsEnabled(boolean isEnabled)
      {
          pref.edit().putBoolean(ANALYTICS_KEY, isEnabled).apply();
      }
  
      @Override
      public boolean isCrashReportingEnabled()
      {
          return pref.getBoolean(CRASH_REPORTING_KEY, true);
      }
  
      @Override
      public void setCrashReportingEnabled(boolean isEnabled)
      {
          pref.edit().putBoolean(CRASH_REPORTING_KEY, isEnabled).apply();
      }
  
      @Override
      public long getLoginTime(String address)
      {
          return pref.getLong(getAddressKey(WALLET_LOGIN_TIME, address), -1);
      }
  
      @Override
      public void logIn(String address)
      {
          pref.edit().putLong(getAddressKey(WALLET_LOGIN_TIME, address), System.currentTimeMillis() / 1000).apply();
      }
  
      @Override
      public void setFirebaseMessagingToken(String token)
      {
          pref.edit().putString(FIREBASE_MESSAGING_TOKEN, token).apply();
      }
  
      @Override
      public String getFirebaseMessagingToken()
      {
          return pref.getString(FIREBASE_MESSAGING_TOKEN, "");
  
      }
  
      @Override
      public boolean isTransactionNotificationsEnabled(String address) {
          return pref.getBoolean(getAddressKey(TRANSACTION_NOTIFICATIONS_ENABLED, address), true);
      }
  
      @Override
      public void setTransactionNotificationEnabled(String address, boolean state) {
          pref.edit().putBoolean(getAddressKey(TRANSACTION_NOTIFICATIONS_ENABLED, address), state).apply();
      }
  
      @Override
      public boolean isPostNotificationsPermissionRequested(String address) {
          return pref.getBoolean(getAddressKey(POST_NOTIFICATIONS_PERMISSION_REQUESTED, address), false);
      }
  
      @Override
      public void setPostNotificationsPermissionRequested(String address, boolean hasRequested)
      {
          pref.edit().putBoolean(getAddressKey(POST_NOTIFICATIONS_PERMISSION_REQUESTED, address), hasRequested).apply();
      }
  
      @Override
      public boolean getUseTSViewer()
      {
          return pref.getBoolean(USE_TOKENSCRIPT_VIEWER, true);
      }
  
      @Override
      public void setUseTSViewer(boolean state)
      {
          pref.edit().putBoolean(USE_TOKENSCRIPT_VIEWER, state).apply();
      }
  
      @NonNull
      private String getAddressKey(String key, String address)
      {
          return key + address.toLowerCase(Locale.ENGLISH);
      }
  }
  