// Copyright 2015-present 650 Industries. All rights reserved.

package versioned.host.exp.exponent.modules.api;

import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.support.annotation.Nullable;
import android.util.DisplayMetrics;

import java.util.Map;
import java.util.UUID;

import com.facebook.device.yearclass.YearClass;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.common.MapBuilder;

import org.json.JSONObject;

import javax.inject.Inject;

import host.exp.exponent.ExponentApplication;
import host.exp.exponent.ExponentManifest;
import host.exp.exponent.kernel.Kernel;
import host.exp.exponent.storage.ExponentSharedPreferences;

public class ConstantsModule extends ReactContextBaseJavaModule {

  @Inject
  ExponentSharedPreferences mExponentSharedPreferences;

  private int mStatusBarHeight = 0;
  private final Map<String, Object> mExperienceProperties;
  private String mSessionId = UUID.randomUUID().toString();
  private JSONObject mManifest;

  private static int convertPixelsToDp(float px, Context context) {
    Resources resources = context.getResources();
    DisplayMetrics metrics = resources.getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return (int) dp;
  }

  public ConstantsModule(
      ReactApplicationContext reactContext,
      ExponentApplication application,
      Map<String, Object> experienceProperties,
      JSONObject manifest) {
    super(reactContext);
    application.getAppComponent().inject(this);

    mManifest = manifest;

    if (!manifest.has(ExponentManifest.MANIFEST_STATUS_BAR_COLOR)) {
      int resourceId = application.getResources().getIdentifier("status_bar_height", "dimen", "android");
      if (resourceId > 0) {
        int statusBarHeightPixels = application.getResources().getDimensionPixelSize(resourceId);
        // Convert from pixels to dip
        mStatusBarHeight = convertPixelsToDp(statusBarHeightPixels, application);
      }
    } else {
      mStatusBarHeight = 0;
    }
    mExperienceProperties = experienceProperties;
  }

  @Override
  public String getName() {
    return "ExponentConstants";
  }

  @Nullable
  @Override
  public Map<String, Object> getConstants() {
    Map<String, Object> constants = MapBuilder.<String, Object>of(
        "sessionId", mSessionId,
        "exponentVersion", Kernel.getVersionName(),
        "statusBarHeight", mStatusBarHeight,
        "deviceYearClass", YearClass.get(getReactApplicationContext()),
        "deviceId", mExponentSharedPreferences.getOrCreateUUID(),
        "deviceName", Build.MODEL,
        "manifest", mManifest.toString()
    );
    if (mExperienceProperties != null) {
      constants.putAll(mExperienceProperties);
    }
    return constants;
  }
}

@@ -283,16 +283,42 @@
 trics;%0A%0A
+import java.util.HashMap;%0A
 import j
@@ -2396,47 +2396,43 @@
 s = 
-MapBuilder.%3CString, Object%3Eof(%0A        
+new HashMap%3C%3E();%0A    constants.put(
 %22ses
@@ -2450,26 +2450,37 @@
 essionId
-,
+);
 %0A    
-    
+constants.put(
 %22exponen
@@ -2513,26 +2513,37 @@
 onName()
-,
+);
 %0A    
-    
+constants.put(
 %22statusB
@@ -2569,26 +2569,37 @@
 arHeight
-,
+);
 %0A    
-    
+constants.put(
 %22deviceY
@@ -2652,26 +2652,37 @@
 ntext())
-,
+);
 %0A    
-    
+constants.put(
 %22deviceI
@@ -2729,26 +2729,37 @@
 teUUID()
-,
+);
 %0A    
-    
+constants.put(
 %22deviceN
@@ -2779,18 +2779,29 @@
 ODEL
-,
+);
 %0A    
-    
+constants.put(
 %22man
@@ -2828,21 +2828,104 @@
 String()
+);
 %0A    
+constants.put(%22isDevice%22, !isRunningOnGenymotion() && !isRunningOnStockEmulator()
 );%0A    i
@@ -3038,11 +3038,223 @@
 nts;%0A  %7D
+%0A%0A  private static boolean isRunningOnGenymotion() %7B%0A    return Build.FINGERPRINT.contains(%22vbox%22);%0A  %7D%0A%0A  private static boolean isRunningOnStockEmulator() %7B%0A    return Build.FINGERPRINT.contains(%22generic%22);%0A  %7D
 %0A%7D%0A

Add isDevice constant