content: package com.alphawallet.app.util;
  
  import static com.alphawallet.app.util.Utils.isValidUrl;
  import static com.alphawallet.ethereum.EthereumNetworkBase.POLYGON_AMOY_ID;
  import static com.alphawallet.ethereum.EthereumNetworkBase.POLYGON_ID;
  import static com.alphawallet.ethereum.EthereumNetworkBase.POLYGON_TEST_ID;
  
  import android.content.Context;
  import android.content.SharedPreferences;
  import android.text.TextUtils;
  
  import androidx.preference.PreferenceManager;
  
  import com.alphawallet.app.C;
  import com.alphawallet.app.entity.DApp;
  import com.google.android.gms.common.util.HttpUtils;
  import com.google.gson.Gson;
  import com.google.gson.reflect.TypeToken;
  
  import java.io.BufferedReader;
  import java.io.BufferedWriter;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  public class DappBrowserUtils
  {
      private static final String DAPPS_LIST_FILENAME = "dapps_list.json";
      private static final String MY_DAPPS_FILE = "mydapps";
      private static final String DAPPS_HISTORY_FILE = "dappshistory";
      private static final String DEFAULT_HOMEPAGE = "https://alphawallet.com/browser/";
      private static final String POLYGON_HOMEPAGE = "https://alphawallet.com/browser-item-category/polygon/";
  
      //TODO: Move to database
      public static void saveToPrefs(Context context, List<DApp> myDapps)
      {
          if (context != null)
          {
              //don't store custom dapps
              List<DApp> primaryDapps = getPrimarySites(context);
              Map<String, DApp> dappMap = new HashMap<>();
              for (DApp d : myDapps)
              {
                  if (isValidUrl(d.getUrl()))
                      dappMap.put(d.getUrl(), d);
              }
              for (DApp d : primaryDapps)
              {
                  dappMap.remove(d.getUrl());
              }
  
              String myDappsJson = new Gson().toJson(dappMap.values());
              storeJsonData(MY_DAPPS_FILE, myDappsJson, context);
          }
      }
  
      private static List<DApp> getPrimarySites(Context context)
      {
          return new ArrayList<>();
      }
  
      //TODO: Move to database
      public static List<DApp> getMyDapps(Context context)
      {
          if (context == null) return new ArrayList<>();
  
          String myDappsJson = loadJsonData(MY_DAPPS_FILE, context);
          if (TextUtils.isEmpty(myDappsJson)) myDappsJson = loadFromPrefsLegacy(context, "my_dapps", MY_DAPPS_FILE); //load legacy
  
          List<DApp> dapps = getPrimarySites(context);
  
          if (!TextUtils.isEmpty(myDappsJson))
          {
              dapps.addAll(new Gson().fromJson(myDappsJson, new TypeToken<ArrayList<DApp>>()
              {
              }.getType()));
          }
  
          return dapps;
      }
  
      //TODO: Remove this from prefs, add to database
      public static List<DApp> getBrowserHistory(Context context)
      {
          if (context == null) return new ArrayList<>();
          String historyJson = loadJsonData(DAPPS_HISTORY_FILE, context);
          if (TextUtils.isEmpty(historyJson)) blankPrefEntry(context, C.DAPP_BROWSER_HISTORY); //blank legacy
  
          List<DApp> history;
          if (historyJson.isEmpty())
          {
              history = new ArrayList<>();
          }
          else
          {
              history = new Gson().fromJson(historyJson, new TypeToken<ArrayList<DApp>>()
              {
              }.getType());
          }
  
          int historyLen = history.size();
  
          history = parseDappHistory(history);
  
          if (historyLen != history.size())
          {
              String dappHistory = new Gson().toJson(history);
              storeJsonData(DAPPS_HISTORY_FILE, dappHistory, context);
          }
  
          return history;
      }
  
      private static List<DApp> parseDappHistory(List<DApp> history)
      {
          boolean requireRefresh = false;
          List<DApp> recodeHistory = new ArrayList<>();
          for (DApp dapp : history)
          {
              if (TextUtils.isEmpty(dapp.getUrl()))
              {
                  continue;
              }
              if (isValidUrl(dapp.getUrl()))
              {
                  recodeHistory.add(dapp);
              }
              else
              {
                  requireRefresh = true;
              }
          }
  
          if (requireRefresh)
          {
              return recodeHistory;
          }
          else
          {
              return history;
          }
      }
  
      private static void storeJsonData(String fName, String json, Context context)
      {
          File file = new File(context.getFilesDir(), fName);
          try (FileOutputStream fos = new FileOutputStream(file))
          {
              BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos));
              writer.write(json);
              writer.flush();
              writer.close();
          }
          catch (Exception e)
          {
              //
          }
      }
  
      public static String loadJsonData(String fName, Context context)
      {
          StringBuilder sb = new StringBuilder();
          File file = new File(context.getFilesDir(), fName);
          try (FileInputStream fis = new FileInputStream(file))
          {
              BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
              String line;
              while ((line = reader.readLine()) != null)
              {
                  sb.append(line).append("\n");
              }
              reader.close();
          }
          catch (Exception e)
          {
              //
          }
  
          return sb.toString();
      }
  
      public static void clearHistory(Context context)
      {
          if (context != null)
          {
              storeJsonData(DAPPS_HISTORY_FILE, "", context);
          }
      }
  
      public static void addToHistory(Context context, DApp dapp)
      {
          if (dapp == null || isWithinHomePage(dapp.getUrl())) return;
          List<DApp> history = new ArrayList<>(Collections.singletonList(dapp));
          history.addAll(getBrowserHistory(context));
          if (history.size() > 1)
          {
              for (int i = 1; i < history.size(); i++)
              {
                  if (history.get(i).getUrl().equals(dapp.getUrl()))
                  {
                      history.remove(i); //remove older item
                      break;
                  }
              }
          }
  
          saveHistory(context, history);
      }
  
      public static void removeFromHistory(Context context, String url)
      {
          List<DApp> history = getBrowserHistory(context);
  
          List<Integer> removeList = new ArrayList<>();
  
          for (int i = 0; i < history.size(); i++)
          {
              if (history.get(i).getUrl().equals(url))
              {
                  removeList.add(i);
              }
          }
  
          removeList.sort((d1, d2) -> Integer.compare(d2, d1));
  
          //remove in reverse order
          for (Integer i : removeList)
          {
              history.remove((int)i);
          }
  
          saveHistory(context, history);
      }
  
      public static String getIconUrl(String url)
      {
          return "https://www.google.com/s2/favicons?sz=128&domain=" + url;
      }
  
      public static List<DApp> getDappsList(Context context)
      {
          ArrayList<DApp> dapps;
          dapps = new Gson().fromJson(Utils.loadJSONFromAsset(context, DAPPS_LIST_FILENAME),
                  new TypeToken<List<DApp>>()
                  {
                  }.getType());
          return dapps;
      }
  
      public static boolean isInDappsList(Context context, String candidateURL)
      {
          List<DApp> knownDapps = getDappsList(context);
          //strip the URL to get only the domain
          String candidateDomain = Utils.getDomainName(candidateURL);
          
          for (DApp dapp : knownDapps)
          {
              String thisDomain = Utils.getDomainName(dapp.getUrl());
              if (candidateDomain.equals(thisDomain))
              {
                  return true;
              }
          }
          return false;
      }
  
      private static void saveHistory(Context context, List<DApp> history)
      {
          if (context != null)
          {
              String dappHistory = new Gson().toJson(history);
              storeJsonData(DAPPS_HISTORY_FILE, dappHistory, context);
          }
      }
  
      //Legacy data, blanked after first restore. TODO: Remove after a few version updates
      private static String loadFromPrefsLegacy(Context context, String key, String fileName)
      {
          SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
          String data = prefs.getString(key, "");
          if (!TextUtils.isEmpty(data))
          {
              blankPrefEntry(context, key);
              storeJsonData(fileName, data, context); //move existing data to file
          }
          else
          {
              data = null;
          }
  
          return data;
      }
  
      //TODO: Remove after a few version updates
      private static void blankPrefEntry(Context context, String key)
      {
          PreferenceManager
                  .getDefaultSharedPreferences(context)
                  .edit()
                  .putString(key, "")
                  .apply();
      }
  
      public static String defaultDapp(long chainId)
      {
          return (chainId == POLYGON_ID || chainId == POLYGON_TEST_ID || chainId == POLYGON_AMOY_ID) ? POLYGON_HOMEPAGE : DEFAULT_HOMEPAGE;
      }
  
      public static boolean isWithinHomePage(String url)
      {
          String homePageRoot = DEFAULT_HOMEPAGE.substring(0, DEFAULT_HOMEPAGE.length() - 1); //remove final slash
          return (url != null && url.startsWith(homePageRoot));
      }
  
      public static boolean isDefaultDapp(String url)
      {
          return (DEFAULT_HOMEPAGE.equals(url)
                  || POLYGON_HOMEPAGE.equals(url));
      }
  }
  