package com.nutomic.syncthingandroid.service;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.util.Log;

import com.nutomic.syncthingandroid.receiver.BatteryReceiver;
import com.nutomic.syncthingandroid.receiver.NetworkReceiver;

import java.util.HashSet;
import java.util.Set;

/**
 * Holds information about the current wifi and charging state of the device.
 *
 * This information is actively read on construction, and then updated from intents that are passed
 * to {@link #update(android.content.Intent)}.
 */
public class DeviceStateHolder {

    private static final String TAG = "DeviceStateHolder";

    /**
     * Intent extra containing a boolean saying whether wifi is connected or not.
     */
    public static final String EXTRA_IS_ALLOWED_NETWORK_CONNECTION =
            "com.nutomic.syncthingandroid.syncthing.DeviceStateHolder.IS_ALLOWED_NETWORK_CONNECTION";

    /**
     * Intent extra containging a boolean saying whether the device is
     * charging or not (any power source).
     */
    public static final String EXTRA_IS_CHARGING =
            "com.nutomic.syncthingandroid.syncthing.DeviceStateHolder.IS_CHARGING";

    private final Context mContext;
    private final SharedPreferences mPreferences;

    private boolean mIsAllowedNetworkConnection = false;
    private String mWifiSsid;
    private boolean mIsCharging = false;

    public DeviceStateHolder(Context context) {
        mContext = context;
        mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);

        BatteryReceiver.updateInitialChargingStatus(mContext);
        NetworkReceiver.updateNetworkStatus(mContext);
    }

    public boolean isCharging() {
        return mIsCharging;
    }

    public boolean isAllowedNetworkConnection() {
        return mIsAllowedNetworkConnection;
    }

    public void update(Intent intent) {
        mIsAllowedNetworkConnection =
                intent.getBooleanExtra(EXTRA_IS_ALLOWED_NETWORK_CONNECTION, mIsAllowedNetworkConnection);
        mIsCharging = intent.getBooleanExtra(EXTRA_IS_CHARGING, mIsCharging);
        Log.i(TAG, "State updated, allowed network connection: " + mIsAllowedNetworkConnection +
                ", charging: " + mIsCharging);

        if (mIsAllowedNetworkConnection) {
            updateWifiSsid();
        } else {
            mWifiSsid = null;
        }
    }

    private void updateWifiSsid() {
        mWifiSsid = null;
        WifiManager wifiManager =
                (WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        // may be null, if WiFi has been turned off in meantime
        if (wifiInfo != null) {
            mWifiSsid = wifiInfo.getSSID();
        }
    }

    private String getWifiSsid() {
        return mWifiSsid;
    }

    /**
     * Determines if Syncthing should currently run.
     */
    public boolean shouldRun() {
        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
                mPreferences.getBoolean("respect_battery_saving", true) &&
                pm.isPowerSaveMode()) {
            return false;
        }
        else if (SyncthingService.alwaysRunInBackground(mContext)) {
            // Check wifi/charging state against preferences and start if ok.
            boolean prefStopMobileData = mPreferences.getBoolean(SyncthingService.PREF_SYNC_ONLY_WIFI, false);
            boolean prefStopNotCharging = mPreferences.getBoolean(SyncthingService.PREF_SYNC_ONLY_CHARGING, false);

            return (isCharging() || !prefStopNotCharging) &&
                    (!prefStopMobileData || isAllowedWifiConnected());
        }
        else {
            return true;
        }
    }

    private boolean isAllowedWifiConnected() {
        boolean wifiConnected = isAllowedNetworkConnection();
        if (wifiConnected) {
            Set<String> ssids = mPreferences.getStringSet(SyncthingService.PREF_SYNC_ONLY_WIFI_SSIDS, new HashSet<>());
            if (ssids.isEmpty()) {
                Log.d(TAG, "All SSIDs allowed for syncing");
                return true;
            } else {
                String ssid = getWifiSsid();
                if (ssid != null) {
                    if (ssids.contains(ssid)) {
                        Log.d(TAG, "SSID [" + ssid + "] found in whitelist: " + ssids);
                        return true;
                    }
                    Log.i(TAG, "SSID [" + ssid + "] not whitelisted: " + ssids);
                    return false;
                } else {
                    // Don't know the SSID (yet) (should not happen?!), so not allowing
                    Log.w(TAG, "SSID unknown (yet), cannot check SSID whitelist. Disallowing sync.");
                    return false;
                }
            }
        }
        Log.d(TAG, "Wifi not connected");
        return false;
    }

}

@@ -107,45 +107,8 @@
 nt;%0A
-import android.content.IntentFilter;%0A
 impo
@@ -2471,129 +2471,25 @@
     
-if (mIsAllowedNetworkConnection) %7B%0A            updateWifiSsid();%0A        %7D else %7B%0A            mWifiSsid = null;%0A        %7D
+updateWifiSsid();
 %0A   
@@ -2913,76 +2913,8 @@
  %7D%0A%0A
-    private String getWifiSsid() %7B%0A        return mWifiSsid;%0A    %7D%0A%0A
     
@@ -3804,36 +3804,44 @@
 ta %7C%7C is
-AllowedWifi
+WhitelistedNetwork
 Connect
-ed
+ion
 ());%0A   
@@ -3930,28 +3930,36 @@
 n is
-AllowedWifi
+WhitelistedNetwork
 Connect
-ed
+ion
 () %7B
@@ -4336,97 +4336,33 @@
     
-String ssid = getWifiSsid();%0A                if (ssid != null) %7B%0A                    if (
+if (mWifiSsid != null && 
 ssid
@@ -4376,17 +4376,22 @@
 ins(
-s
+mWifiS
 sid)) %7B%0A
     
@@ -4382,28 +4382,24 @@
 ifiSsid)) %7B%0A
-    
             
@@ -4420,33 +4420,38 @@
 TAG, %22SSID %5B%22 + 
-s
+mWifiS
 sid + %22%5D found i
@@ -4487,36 +4487,32 @@
                 
-    
 return true;%0A   
@@ -4516,37 +4516,40 @@
                 
-    %7D
+%7D else %7B
 %0A               
@@ -4549,33 +4549,33 @@
             Log.
-i
+w
 (TAG, %22SSID %5B%22 +
@@ -4575,17 +4575,22 @@
 ID %5B%22 + 
-s
+mWifiS
 sid + %22%5D
@@ -4594,253 +4594,22 @@
  %22%5D 
-not whitelisted: %22 + ssids);%0A                    return false;%0A                %7D else %7B%0A                    // Don't know the SSID (yet) (should not happen?!), so not allowing%0A                    Log.w(TAG, %22SSID unknown (yet), cannot check SSID
+unknown or not
  whi
@@ -4618,11 +4618,13 @@
 list
-. D
+ed, d
 isal

Simplify DeviceStateHolder code