/*
 * Copyright 2015 OpenMarket Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.matrix.console.store;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import com.google.gson.Gson;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.matrix.androidsdk.HomeserverConnectionConfig;
import org.matrix.androidsdk.rest.model.login.Credentials;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * Stores login credentials in SharedPreferences.
 */
public class LoginStorage {
    private static final String LOG_TAG = "LoginStorage";

    public static final String PREFS_LOGIN = "org.matrix.console.store.LoginStorage";

    // one account
    public static final String PREFS_KEY_USERNAME = "org.matrix.console.store.LoginStorage.PREFS_KEY_USERNAME";
    public static final String PREFS_KEY_HOME_SERVER = "org.matrix.console.store.LoginStorage.PREFS_KEY_HOME_SERVER";
    public static final String PREFS_KEY_ACCESS_TOKEN = "org.matrix.console.store.LoginStorage.PREFS_KEY_ACCESS_TOKEN";

    // multi accounts
    public static final String PREFS_KEY_USERNAMES = "org.matrix.console.store.LoginStorage.PREFS_KEY_USERNAMES";
    public static final String PREFS_KEY_HOME_SERVERS = "org.matrix.console.store.LoginStorage.PREFS_KEY_HOME_SERVERS";
    public static final String PREFS_KEY_ACCESS_TOKENS = "org.matrix.console.store.LoginStorage.PREFS_KEY_ACCESS_TOKENS";

    // multi accounts + HomeserverConnectionConfig
    public static final String PREFS_KEY_CONNECTION_CONFIGS = "org.matrix.console.store.LoginStorage.PREFS_KEY_CONNECTION_CONFIGS";

    private Context mContext;
    private Gson mGson;

    public LoginStorage(Context appContext) {
        mContext = appContext.getApplicationContext();
        mGson = new Gson();
    }

    private String serialize(ArrayList<String> list) {
        if (null == list) {
            return null;
        }
        return mGson.toJson(list);
    }

    private ArrayList<String> deserialize(String listAsString) {
        if (null == listAsString) {
            return null;
        }

        return new ArrayList(Arrays.asList(mGson.fromJson(listAsString,String[].class)));
    }

    /**
     * Return a list of HomeserverConnectionConfig.
     * @return a list of HomeserverConnectionConfig.
     */
    public ArrayList<HomeserverConnectionConfig> getCredentialsList() {
        SharedPreferences prefs = mContext.getSharedPreferences(PREFS_LOGIN, Context.MODE_PRIVATE);

        String connectionConfigsString = prefs.getString(PREFS_KEY_CONNECTION_CONFIGS, null);

        if (connectionConfigsString == null) {
            return new ArrayList<HomeserverConnectionConfig>();
        }

        try {

            JSONArray connectionConfigsStrings = new JSONArray(connectionConfigsString);

            ArrayList<HomeserverConnectionConfig> configList = new ArrayList<HomeserverConnectionConfig>(
                    connectionConfigsStrings.length()
            );

            for (int i = 0; i < connectionConfigsStrings.length(); i++) {
                configList.add(
                        HomeserverConnectionConfig.fromJson(connectionConfigsStrings.getJSONObject(i))
                );
            }

            return configList;
        } catch (JSONException e) {
            Log.e(LOG_TAG, "Failed to deserialize accounts " + e.getMessage(), e);
            throw new RuntimeException("Failed to deserialize accounts");
        }
    }

    /**
     * Add a credentials to the credentials list
     * @param config the HomeserverConnectionConfig to add.
     * @return true if the HomeserverConnectionConfig has been succcessfully added
     */
    public boolean addCredentials(HomeserverConnectionConfig config) {
        if (null != config) {
            SharedPreferences prefs = mContext.getSharedPreferences(PREFS_LOGIN, Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = prefs.edit();

            ArrayList<HomeserverConnectionConfig> configs = getCredentialsList();

            configs.add(config);

            ArrayList<JSONObject> serialized = new ArrayList<JSONObject>(configs.size());

            try {
                for (HomeserverConnectionConfig c : configs) {
                    serialized.add(c.toJson());
                }
            } catch (JSONException e) {
                throw new RuntimeException("Failed to serialize connection config");
            }

            editor.putString(PREFS_KEY_CONNECTION_CONFIGS, new JSONArray(serialized).toString());

            return editor.commit();
        }

        return false;
    }

    /**
     * Remove the credentials from credentials list
     * @param config teh credentials to remove
     * @return
     */
    public Boolean removeCredentials(HomeserverConnectionConfig config) {
        if (null != config) {
            SharedPreferences prefs = mContext.getSharedPreferences(PREFS_LOGIN, Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = prefs.edit();

            ArrayList<HomeserverConnectionConfig> configs = getCredentialsList();
            ArrayList<JSONObject> serialized = new ArrayList<JSONObject>(configs.size());

            boolean found = false;
            try {
                for (HomeserverConnectionConfig c : configs) {
                    if (c.getCredentials().userId.equals(config.getCredentials().userId)) {
                        found = true;
                    } else {
                        serialized.add(c.toJson());
                    }
                }
            } catch (JSONException e) {
                throw new RuntimeException("Failed to serialize connection config");
            }

            if (!found) return false;

            editor.putString(PREFS_KEY_CONNECTION_CONFIGS, new JSONArray(serialized).toString());

            return editor.commit();
        }

        return false;
    }
}

@@ -4161,91 +4161,8 @@
 dd.%0A
-     * @return true if the HomeserverConnectionConfig has been succcessfully added%0A
     
@@ -4176,23 +4176,20 @@
  public 
-boolean
+void
  addCred
@@ -5025,77 +5025,17 @@
 ));%0A
-%0A            return editor.commit();%0A        %7D%0A%0A        return false;
+        %7D
 %0A   
@@ -5183,15 +5183,12 @@
 lic 
-Boolean
+void
  rem
@@ -6144,22 +6144,16 @@
 ) return
- false
 ;%0A%0A     
@@ -6249,77 +6249,17 @@
 ));%0A
-%0A            return editor.commit();%0A        %7D%0A%0A        return false;
+        %7D
 %0A   

Remove unused return values