/*
 *  Copyright (c) 2018-present, Facebook, Inc.
 *
 *  This source code is licensed under the MIT license found in the LICENSE
 *  file in the root directory of this source tree.
 *
 */

package com.facebook.sonar.plugins.sharedpreferences;

import static android.content.Context.MODE_PRIVATE;

import android.content.Context;
import android.content.SharedPreferences;
import com.facebook.sonar.core.SonarConnection;
import com.facebook.sonar.core.SonarObject;
import com.facebook.sonar.core.SonarPlugin;
import com.facebook.sonar.core.SonarReceiver;
import com.facebook.sonar.core.SonarResponder;
import java.util.Map;

public class SharedPreferencesSonarPlugin implements SonarPlugin {

  private SonarConnection mConnection;
  private final SharedPreferences mSharedPreferences;

  public SharedPreferencesSonarPlugin(Context context) {
    mSharedPreferences = context.getSharedPreferences(context.getPackageName(), MODE_PRIVATE);

    mSharedPreferences.registerOnSharedPreferenceChangeListener(
        new SharedPreferences.OnSharedPreferenceChangeListener() {
          @Override
          public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            if (mConnection != null) {
              mConnection.send(
                  "sharedPreferencesChange",
                  new SonarObject.Builder()
                      .put("name", key)
                      .put("deleted", !mSharedPreferences.contains(key))
                      .put("time", System.currentTimeMillis())
                      .put("value", mSharedPreferences.getAll().get(key))
                      .build());
            }
          }
        });
  }

  @Override
  public String getId() {
    return "Preferences";
  }

  private SonarObject getSharedPreferencesObject() {
    final SonarObject.Builder builder = new SonarObject.Builder();
    final Map<String, ?> map = mSharedPreferences.getAll();

    for (Map.Entry<String, ?> entry : map.entrySet()) {
      final Object val = entry.getValue();
      builder.put(entry.getKey(), val);
    }

    return builder.build();
  }

  @Override
  public void onConnect(SonarConnection connection) {
    mConnection = connection;

    connection.receive(
        "getSharedPreferences",
        new SonarReceiver() {
          @Override
          public void onReceive(SonarObject params, SonarResponder responder) {
            responder.success(getSharedPreferencesObject());
          }
        });

    connection.receive(
        "setSharedPreference",
        new SonarReceiver() {
          @Override
          public void onReceive(SonarObject params, SonarResponder responder)
              throws IllegalArgumentException {

            String preferenceName = params.getString("preferenceName");
            Object originalValue = mSharedPreferences.getAll().get(preferenceName);
            SharedPreferences.Editor editor = mSharedPreferences.edit();

            if (originalValue instanceof Boolean) {
              editor.putBoolean(preferenceName, params.getBoolean("preferenceValue"));
            } else if (originalValue instanceof Long) {
              editor.putLong(preferenceName, params.getLong("preferenceValue"));
            } else if (originalValue instanceof Integer) {
              editor.putInt(preferenceName, params.getInt("preferenceValue"));
            } else if (originalValue instanceof Float) {
              editor.putFloat(preferenceName, params.getFloat("preferenceValue"));
            } else if (originalValue instanceof String) {
              editor.putString(preferenceName, params.getString("preferenceValue"));
            } else {
              throw new IllegalArgumentException("Type not supported: " + preferenceName);
            }

            editor.apply();

            responder.success(getSharedPreferencesObject());
          }
        });
  }

  @Override
  public void onDisconnect() {
    mConnection = null;
  }
}

@@ -784,141 +784,714 @@
 %0A%0A  
-public SharedPreferencesSonarPlugin(Context context) %7B%0A    mSharedPreferences = context.getSharedPreferences(context.getPackageN
+/**%0A   * Creates a %7B@link android.content.SharedPreferences%7D plugin for Sonar%0A   *%0A   * @param context The context to retrieve the file from. Will use the package name as the file%0A   *     name with %7B@link Context#MODE_PRIVATE%7D.%0A   */%0A  public SharedPreferencesSonarPlugin(Context context) %7B%0A    this(context, context.getPackageName());%0A  %7D%0A%0A  /**%0A   * Creates a %7B@link android.content.SharedPreferences%7D plugin for Sonar%0A   *%0A   * @param context The context to retrieve the file from. Will use the name as the file name with%0A   *     %7B@link Context#MODE_PRIVATE%7D.%0A   * @param name The preference file name.%0A   */%0A  public SharedPreferencesSonarPlugin(Context context, String name) %7B%0A    this(context, n
 ame
-()
 , MO
@@ -1502,16 +1502,407 @@
 RIVATE);
+%0A  %7D%0A%0A  /**%0A   * Creates a %7B@link android.content.SharedPreferences%7D plugin for Sonar%0A   *%0A   * @param context The context to retrieve the file from.%0A   * @param name The preference file name.%0A   * @param mode The Context mode to utilize.%0A   */%0A  public SharedPreferencesSonarPlugin(Context context, String name, int mode) %7B%0A    mSharedPreferences = context.getSharedPreferences(name, mode);
 %0A%0A    mS

Make the shared preferences plugin more flexible