package com.agilefreaks.calin.securityflaxexample;

import android.util.Log;

import java.security.Security;
import java.util.HashMap;
import java.util.Map;

/*
Things to consider:
- clarity with respect to security (we want to look at a abstraction and the security model should be very clear)
- catch flaws at compile time
- proper usage to be obvious
- separate and protect security state
 */

/*
Build abstractions that are hard to use insecurely
 */

/*
Add a enum
 */

/*
Expanding the bounds of values for our security level, increases complexity
 */

public class StorageStrategy {
  public static final int MAX_SECURITY = 1;
  public static final int NO_SECURITY = 0;
  public static final int REQUIRE_ENCRYPTION = 3;


  private interface StorageHandler {
    public void store(String key, String data);
  }

  private class PublicStoreAdapter implements StorageHandler {

    @Override
    public void store(String key, String data) {
      Log.d("PublicStoreAdapter", "Store on sdcard");
    }
  }

  private class PrivateStoreAdapter implements StorageHandler {

    @Override
    public void store(String key, String data) {
      Log.d("PublicStoreAdapter", "Store on private folder");
    }
  }

  private Map<String, StorageHandler> handlerMapping = new HashMap<String, StorageHandler>();

  public StorageStrategy() {
    handlerMapping.put("private", new PrivateStoreAdapter());
    handlerMapping.put("public", new PublicStoreAdapter());
  }

  public void storeData(String key, String data, int security) {
    StorageHandler storageHandler;

    if (security < REQUIRE_ENCRYPTION) {
      storageHandler = getPublicHandler();
    } else {
      storageHandler = getSecureHandler();
    }

    storageHandler.store(key, data);
  }

  private StorageHandler getPublicHandler() {
    return handlerMapping.get("public");
  }

  private StorageHandler getSecureHandler() {
    return handlerMapping.get("private");
  }

  public void saveSettings() {
    storeData("name", "private stuff", MAX_SECURITY);
    storeData("private.groups", "some more private stuff", MAX_SECURITY);
    storeData("address", "private address", MAX_SECURITY);

    storeData("profilephoto", "public info", NO_SECURITY);
    storeData("homepageurl", "public info", NO_SECURITY);
  }
}

@@ -75,39 +75,8 @@
 g;%0A%0A
-import java.security.Security;%0A
 impo
@@ -441,260 +441,73 @@
 */%0A%0A
-/*%0AExpanding the bounds of values for our security level, increases complexity%0A */%0A%0Apublic class StorageStrategy %7B%0A  public static final int MAX_SECURITY = 1;%0A  public static final int NO_SECURITY = 0;%0A  public static final int REQUIRE_ENCRYPTION = 3;%0A
+public class StorageStrategy %7B%0A  public enum Security %7BMAX, NONE%7D
 %0A%0A  
@@ -1287,19 +1287,24 @@
 g data, 
-int
+Security
  securit
@@ -1365,28 +1365,24 @@
 ity 
-%3C REQUIRE_ENCRYPTI
+== Security.N
 ON
+E
 ) %7B%0A
@@ -1780,36 +1780,36 @@
 ate stuff%22, 
-MAX_SECURITY
+Security.MAX
 );%0A    store
@@ -1858,28 +1858,28 @@
 stuff%22, 
-MAX_SECURITY
+Security.MAX
 );%0A    s
@@ -1921,20 +1921,20 @@
 s%22, 
-MAX_SECURITY
+Security.MAX
 );%0A%0A
@@ -1974,35 +1974,37 @@
 blic info%22, 
-NO_SECURITY
+Security.NONE
 );%0A    store
@@ -2042,19 +2042,21 @@
 o%22, 
-NO_SECURITY
+Security.NONE
 );%0A 

revert to the good aproach and guard our security level with compile time