// Path: opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/PreferenceDataSource.java
// public class PreferenceDataSource {
// 
//     private static final String LAST_LIBRARY_CONFIG_UPDATE = "last_library_config_update";
//     private static final String LAST_LIBRARY_CONFIG_UPDATE_TRY = "last_library_config_update_try";
//     private static final String LAST_LIBRARY_CONFIG_UPDATE_VERSION =
//             "last_library_config_update_version";
//     private static final String ACCOUNT_PTR_HINT_SHOWN = "account_ptr_hint_shown";
//     protected SharedPreferences sp;
//     protected Context context;
// 
//     private static final String LAST_LIBRARY_CONFIG_UPDATE_FILE = "last_library_config_update.txt";
// 
//     public PreferenceDataSource(Context context) {
//         this.context = context;
//         sp = PreferenceManager.getDefaultSharedPreferences(context);
//     }
// 
//     public long getLastLibraryConfigUpdateTry() {
//         return sp.getLong(LAST_LIBRARY_CONFIG_UPDATE_TRY, 0);
//     }
// 
//     @Nullable
//     public DateTime getLastLibraryConfigUpdate() {
//         String lastUpdate = sp.getString(LAST_LIBRARY_CONFIG_UPDATE, null);
//         if (lastUpdate == null || getLastLibraryConfigUpdateVersion() != BuildConfig.VERSION_CODE) {
//             // last update only makes sense if done using the current app version
//             try {
//                 InputStream is = context.getAssets().open(LAST_LIBRARY_CONFIG_UPDATE_FILE);
//                 return new DateTime(Utils.readStreamToString(is));
//             } catch (IOException e) {
//                 return null;
//             }
//         }
//         return new DateTime(lastUpdate);
//     }
// 
//     @Nullable
//     public DateTime getBundledConfigUpdateTime() {
//         try {
//             InputStream is = context.getAssets().open(LAST_LIBRARY_CONFIG_UPDATE_FILE);
//             return new DateTime(Utils.readStreamToString(is));
//         } catch (IOException e) {
//             return null;
//         }
//     }
// 
//     public void setLastLibraryConfigUpdate(DateTime lastUpdate) {
//         sp.edit().putString(LAST_LIBRARY_CONFIG_UPDATE, lastUpdate.toString()).apply();
//     }
// 
//     public void setLastLibraryConfigUpdateTry(long lastUpdate) {
//         sp.edit().putLong(LAST_LIBRARY_CONFIG_UPDATE_TRY, lastUpdate).apply();
//     }
// 
//     public boolean hasBundledConfiguration() {
//         return getBundledConfigUpdateTime() != null;
//     }
// 
//     public void clearLastLibraryConfigUpdate() {
//         sp.edit()
//           .remove(LAST_LIBRARY_CONFIG_UPDATE)
//           .remove(LAST_LIBRARY_CONFIG_UPDATE_TRY)
//           .remove(LAST_LIBRARY_CONFIG_UPDATE_VERSION)
//           .apply();
//     }
// 
//     public int getLastLibraryConfigUpdateVersion() {
//         return sp.getInt(LAST_LIBRARY_CONFIG_UPDATE_VERSION, 0);
//     }
// 
//     public void setLastLibraryConfigUpdateVersion(int lastUpdateVersion) {
//         sp.edit().putInt(LAST_LIBRARY_CONFIG_UPDATE_VERSION, lastUpdateVersion).apply();
//     }
// 
//     public boolean isLoadCoversOnDataPreferenceSet() {
//         return sp.getBoolean("on_data_load_covers", true);
//     }
// 
//     public void setAccountPtrHintShown(int number) {
//         sp.edit().putInt(ACCOUNT_PTR_HINT_SHOWN, number).apply();
//     }
// 
//     public int getAccountPtrHintShown() {
//         return sp.getInt(ACCOUNT_PTR_HINT_SHOWN, 0);
//     }
// }


import org.joda.time.DateTime;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.List;
import de.geeksfactory.opacclient.BuildConfig;
import de.geeksfactory.opacclient.objects.Library;
import de.geeksfactory.opacclient.storage.PreferenceDataSource;
import de.geeksfactory.opacclient.storage.SearchFieldDataSource;
import retrofit2.Response;
    public int updateConfig(WebService service, PreferenceDataSource prefs,
            LibraryConfigUpdateService.FileOutput output,
            SearchFieldDataSource searchFields)
            throws IOException, JSONException {
        DateTime last_update = prefs.getLastLibraryConfigUpdate();
        if (prefs.getLastLibraryConfigUpdateVersion() != BuildConfig.VERSION_CODE) {
            last_update = prefs.getBundledConfigUpdateTime();
        }

        Response<List<Library>> response = getServerResponse(service, last_update);
        if (!response.isSuccessful()) {
            throw new IOException(String.valueOf(response.code()));
        }

        if (prefs.getLastLibraryConfigUpdateVersion() != BuildConfig.VERSION_CODE) {
            output.clearFiles();
        }

        List<Library> updatedLibraries = response.body();

        for (Library lib : updatedLibraries) {
            if (lib == null) {
                continue;
            }
            String filename = lib.getIdent() + ".json";
            JSONObject json = lib.toJSON();
            output.writeFile(filename, json.toString());

            if (searchFields.hasSearchFields(lib.getIdent())) {
                // clear cached search fields when configuration was updated
// Path: opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/PreferenceDataSource.java
// public class PreferenceDataSource {
// 
//     private static final String LAST_LIBRARY_CONFIG_UPDATE = "last_library_config_update";
//     private static final String LAST_LIBRARY_CONFIG_UPDATE_TRY = "last_library_config_update_try";
//     private static final String LAST_LIBRARY_CONFIG_UPDATE_VERSION =
//             "last_library_config_update_version";
//     private static final String ACCOUNT_PTR_HINT_SHOWN = "account_ptr_hint_shown";
//     protected SharedPreferences sp;
//     protected Context context;
// 
//     private static final String LAST_LIBRARY_CONFIG_UPDATE_FILE = "last_library_config_update.txt";
// 
//     public PreferenceDataSource(Context context) {
//         this.context = context;
//         sp = PreferenceManager.getDefaultSharedPreferences(context);
//     }
// 
//     public long getLastLibraryConfigUpdateTry() {
//         return sp.getLong(LAST_LIBRARY_CONFIG_UPDATE_TRY, 0);
//     }
// 
//     @Nullable
//     public DateTime getLastLibraryConfigUpdate() {
//         String lastUpdate = sp.getString(LAST_LIBRARY_CONFIG_UPDATE, null);
//         if (lastUpdate == null || getLastLibraryConfigUpdateVersion() != BuildConfig.VERSION_CODE) {
//             // last update only makes sense if done using the current app version
//             try {
//                 InputStream is = context.getAssets().open(LAST_LIBRARY_CONFIG_UPDATE_FILE);
//                 return new DateTime(Utils.readStreamToString(is));
//             } catch (IOException e) {
//                 return null;
//             }
//         }
//         return new DateTime(lastUpdate);
//     }
// 
//     @Nullable
//     public DateTime getBundledConfigUpdateTime() {
//         try {
//             InputStream is = context.getAssets().open(LAST_LIBRARY_CONFIG_UPDATE_FILE);
//             return new DateTime(Utils.readStreamToString(is));
//         } catch (IOException e) {
//             return null;
//         }
//     }
// 
//     public void setLastLibraryConfigUpdate(DateTime lastUpdate) {
//         sp.edit().putString(LAST_LIBRARY_CONFIG_UPDATE, lastUpdate.toString()).apply();
//     }
// 
//     public void setLastLibraryConfigUpdateTry(long lastUpdate) {
//         sp.edit().putLong(LAST_LIBRARY_CONFIG_UPDATE_TRY, lastUpdate).apply();
//     }
// 
//     public boolean hasBundledConfiguration() {
//         return getBundledConfigUpdateTime() != null;
//     }
// 
//     public void clearLastLibraryConfigUpdate() {
//         sp.edit()
//           .remove(LAST_LIBRARY_CONFIG_UPDATE)
//           .remove(LAST_LIBRARY_CONFIG_UPDATE_TRY)
//           .remove(LAST_LIBRARY_CONFIG_UPDATE_VERSION)
//           .apply();
//     }
// 
//     public int getLastLibraryConfigUpdateVersion() {
//         return sp.getInt(LAST_LIBRARY_CONFIG_UPDATE_VERSION, 0);
//     }
// 
//     public void setLastLibraryConfigUpdateVersion(int lastUpdateVersion) {
//         sp.edit().putInt(LAST_LIBRARY_CONFIG_UPDATE_VERSION, lastUpdateVersion).apply();
//     }
// 
//     public boolean isLoadCoversOnDataPreferenceSet() {
//         return sp.getBoolean("on_data_load_covers", true);
//     }
// 
//     public void setAccountPtrHintShown(int number) {
//         sp.edit().putInt(ACCOUNT_PTR_HINT_SHOWN, number).apply();
//     }
// 
//     public int getAccountPtrHintShown() {
//         return sp.getInt(ACCOUNT_PTR_HINT_SHOWN, 0);
//     }
// }


// Path: opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/webservice/UpdateHandler.java
import org.joda.time.DateTime;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.List;
import de.geeksfactory.opacclient.BuildConfig;
import de.geeksfactory.opacclient.objects.Library;
import de.geeksfactory.opacclient.storage.PreferenceDataSource;
import de.geeksfactory.opacclient.storage.SearchFieldDataSource;
import retrofit2.Response;

    public int updateConfig(WebService service, PreferenceDataSource prefs,
            LibraryConfigUpdateService.FileOutput output,
            SearchFieldDataSource searchFields)
            throws IOException, JSONException {
        DateTime last_update = prefs.getLastLibraryConfigUpdate();
        if (prefs.getLastLibraryConfigUpdateVersion() != BuildConfig.VERSION_CODE) {
            last_update = prefs.getBundledConfigUpdateTime();
        }

        Response<List<Library>> response = getServerResponse(service, last_update);
        if (!response.isSuccessful()) {
            throw new IOException(String.valueOf(response.code()));
        }

        if (prefs.getLastLibraryConfigUpdateVersion() != BuildConfig.VERSION_CODE) {
            output.clearFiles();
        }

        List<Library> updatedLibraries = response.body();

        for (Library lib : updatedLibraries) {
            if (lib == null) {
                continue;
            }
            String filename = lib.getIdent() + ".json";
            JSONObject json = lib.toJSON();
            output.writeFile(filename, json.toString());

            if (searchFields.hasSearchFields(lib.getIdent())) {
                // clear cached search fields when configuration was updated
                searchFields.clearSearchFields(lib.getIdent());