package com.quantumics;
import android.app.ActivityManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.util.Log;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import cz.msebera.android.httpclient.Header;


public class Sensor extends BroadcastReceiver {

    private static String userId;
    private static String username;
    private static String deviceId;
    private static String mode;
    private static String state;
    private static Context context;
    private static DBHelper db;


    public static String SENSOR_STATE_ACTION="com.quantumics.proximity.SENSOR_STATE";
    public static String SENSOR_RESTART_ACTION="com.quantumics.proximity.SENSOR_RESTART";
    public static String GEOLOCATION_SETTINGS_ACTION ="com.quantumics.proximity.GEOLOCATION_SETTINGS_ACTIVITY";
    public static String SENSOR_REQUEST_PERMISSIONS = "com.quantumics.proximity.REQUEST_PERMISSIONS";
    public static String USERNAME = "username";
    public static String USERID="userId";
    public static String DEVICEID="deviceId";
    public static String STATE="state";
    public static String MODE = "mode";
    private static String BACKEND_URL = "https://192.168.8.100";



    private static AsyncHttpClient client = new AsyncHttpClient();



    public static boolean networkAvailable(Context context) {
        ConnectivityManager cm = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        return (netInfo != null && netInfo.isConnected());
    }


    private static void initializeDB(Context context){
        db = new DBHelper(context);
    }




    private static boolean isMyServiceRunning(Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }


    @Override
    public void onReceive(Context mContext, Intent intent) {
        context = mContext;
        if(db==null)initializeDB(context);
        String action = intent.getAction();
        try{
            userId = intent.getStringExtra(USERID);
            username = intent.getStringExtra(USERNAME);
            deviceId = intent.getStringExtra(DEVICEID);
            mode = intent.getStringExtra(MODE);
            if(action.equals(SENSOR_STATE_ACTION)){
                String switch_action = intent.getStringExtra(STATE);
                if(switch_action.equals("ON")){
                    state = "ON";
                    this.initSensor(context);
                }else if(switch_action.equals("OFF")){
                    state = "OFF";
                    this.offSensors(context);
                }
            }
            else if(action.equals(SENSOR_RESTART_ACTION)){
                if(state.equals("ON")){
                    this.restartSensor(context);
                }
            }
        }
        catch (NullPointerException e){
            Log.e("SENSOR SERVICE", e.getMessage());
        }
    }


    private void initSensor(Context context){
        Log.v("PROXIMITY SENSOR", "INITIALIZING SENSOR");
        if(mode.equals("WIFI")){
            initWifiDeviceListener(context);
        }
        else if(mode.equals("WIFIDIRECT")){
            initWifiP2PDeviceListener(context);
        }
        else if(mode.equals("GEOLOCATION")){
            initGeolocationListener(context);
        }
    }


    private void restartSensor(Context context){
        initSensor(context);
        offSensors(context);
    }


    private void initWifiDeviceListener(final Context context){
        Log.v("PROXIMITY SENSOR", "INITIALIZING WIFI DEVICE LISTENER");
        if(!isMyServiceRunning(WifiService.class)){
            Intent wifiListener = new Intent(context, WifiService.class);
            wifiListener.setPackage(this.getClass().getPackage().getName());
            wifiListener.putExtra(DEVICEID, deviceId);
            wifiListener.putExtra(USERID, userId);
            wifiListener.putExtra(USERNAME, username);
            context.startService(wifiListener);
        }
    }


    private void initWifiP2PDeviceListener(final Context context){
        Log.v("PROXIMITY SENSOR","INITIAILIZING WIFIDIRECT DEVICE LISTENER");
        if(!isMyServiceRunning(WifiP2PService.class)){
            Intent wifiP2PListener = new Intent(context, WifiP2PService.class);
            wifiP2PListener.setPackage(this.getClass().getPackage().getName());
            wifiP2PListener.putExtra(DEVICEID, deviceId);
            wifiP2PListener.putExtra(USERID, userId);
            wifiP2PListener.putExtra(USERNAME, username);
            context.startService(wifiP2PListener);
        }
    }


    private void initGeolocationListener(final Context context){
        Log.v("PROXIMITY SENSOR","INITIALIZING GEOLOCATION LISTENER");
        if(!isMyServiceRunning(GeolocationService.class)){
            Intent geolocationListener = new Intent(context, GeolocationService.class);
            geolocationListener.setPackage(this.getClass().getPackage().getName());
            geolocationListener.putExtra(DEVICEID, deviceId);
            geolocationListener.putExtra(USERID, userId);
            geolocationListener.putExtra(USERNAME, username);
            context.startService(geolocationListener);
        }
    }


    private void offWifiDevice(Context context){
        Log.v("PROXIMITY SENSOR","OFF WIFI SENSOR");
        if(isMyServiceRunning(WifiService.class)){
            Intent wifiListener = new Intent(context, WifiService.class);
            wifiListener.setPackage(this.getClass().getPackage().getName());
            context.stopService(wifiListener);
        }
    }


    private void offWifiP2PDevice(Context context){
        Log.v("PROXIMITY SENSOR", "OFF WIFIDIRECT SENSOR");
        if(isMyServiceRunning(WifiP2PService.class)){
            Intent wifiP2PListener = new Intent(context, WifiP2PService.class);
            wifiP2PListener.setPackage(this.getClass().getPackage().getName());
            context.stopService(wifiP2PListener);
        }
    }


    private void offGeolocationDevice(Context context){
        Log.v("PROXIMITY SENSOR", "OFF GEOLOCATION SENSOR");
        if(isMyServiceRunning(GeolocationService.class)){
            Intent geolocationListener = new Intent(context, GeolocationService.class);
            geolocationListener.setPackage(this.getClass().getPackage().getName());
            context.stopService(geolocationListener);
        }
    }


    private void offSensors(Context context){
        Log.v("PROXIMITY SENSOR","OFF ALL SENSORS");
        this.offWifiDevice(context);
        this.offWifiP2PDevice(context);
        this.offGeolocationDevice(context);
    }


    private static long updateLocal(String path, String object){
        if(path.equals("WIFI")){
            DBHelper.WifiData wifiData = new DBHelper.WifiData();
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
            wifiData.setTimestamp(timestamp.getTime()+"");
            wifiData.setWifiData(object);
            return db.insertWifiData(object);
        }
        else if(path.equals("WIFIDIRECT")){
            DBHelper.WifiP2PData wifiP2PData = new DBHelper.WifiP2PData();
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
            wifiP2PData.setTimestamp(timestamp.getTime()+"");
            wifiP2PData.setWifiP2PData(object);
            return db.insertWifiP2PData(object);
        }
        else if(path.equals("GEOLOCATION")){
            DBHelper.GeolocationData geolocationData = new DBHelper.GeolocationData();
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
            geolocationData.setTimestamp(timestamp.getTime()+"");
            geolocationData.setGeolocationData(object);
            return db.insertGeolocation(object);
        }
        return -1;
    }


    private static String getJSONString(Object object) throws JsonProcessingException{
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(object);
    }


    private static void updateCloud(String path, String json) throws IOException{
        RequestParams requestParams = new RequestParams("data", json);
        username="professorbashorun";
        requestParams.put(USERNAME, username);
        requestParams.put(USERID, userId);
        requestParams.put(DEVICEID, deviceId);
        client.post(BACKEND_URL + "/" + username + "/"+userId+"/"+deviceId+"/"+ path, requestParams, new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                Log.v("SENSOR", "DATA UPLOADED SUCCESSFULLY");;
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                Log.v("SENSOR", "DATA UPLOAD FAILED");

            }
        });
    }


    public static class WifiService extends Service{

        private final static int DEFAULT_VALUE = -1;
        private WifiManager mWifiManager;
        private WifiBroadcastReceiver mWifiScanReceiver;
        private List<ScanResult> pScanResults = new ArrayList<>();
        private Timer mTimer;
        private Handler mHandler = new Handler();
        long notify_interval = 15000;


        public WifiService(){

        }


        public class WifiBroadcastReceiver extends BroadcastReceiver{

            @Override
            public void onReceive(Context c, Intent intent) {
                if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                    List<ScanResult> mScanResults = mWifiManager.getScanResults();
                    checkChangesAndUpdate(mScanResults);
                }
            }
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            try{
                Log.v("PROXIMITY SENSOR", "WIFI SERVICE STARTING");
                mWifiScanReceiver = new WifiBroadcastReceiver();
                mWifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
                registerReceiver(mWifiScanReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
                mTimer = new Timer();
                mTimer.schedule(new TimerTaskToGetWifiDevices(), 5,notify_interval);
            }
            catch (Exception e){
                Log.e("PROXIMITY SENSOR", e.getMessage());
            }
            return super.onStartCommand(intent, flags, startId);
        }



        private class TimerTaskToGetWifiDevices extends TimerTask {
            @Override
            public void run() {

                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.v("PROXIMITY SENSOR", "WIFI SERVICE SCANNING");
                        mWifiManager.startScan();
                    }
                });

            }
        }


        @Nullable @Override
        public IBinder onBind(Intent intent) {
            return null;
        }


        public static <T> boolean listEqualsIgnoreOrder(List<T> list1, List<T> list2) {
            return list1.toString().equals(list2.toString());
        }


        private void checkChangesAndUpdate(List<ScanResult> scanResults){
            try{
                Log.v("PROXIMITY SENSOR", "WIFI SCANNED RESULTS COMPARISON: "+scanResults.toString());
                Log.v("PROXIMITY SENSOR", "WIFI SCANNED RESULTS COMPARISON: "+listEqualsIgnoreOrder(scanResults, pScanResults));
                if(!listEqualsIgnoreOrder(scanResults, pScanResults)){
                    pScanResults = scanResults;
                    updateWifiDevices(scanResults);
                }
            }
            catch (Exception e){
                Log.e("PROXIMITY SENSOR", e.getMessage());
            }
        }


        private void updateWifiDevices(List<ScanResult> scanResults){
            try{
                Log.d("PROXIMITY SENSOR", "UPDATING WIFI SCANNED RESULTS");
                String jsonString  = getJSONString(scanResults);
                if(!jsonString.trim().isEmpty() || scanResults.size() != 0){
                    if(!networkAvailable(this)){
                        updateLocal("WIFI", jsonString);
                    }
                    else{
                        syncWifiData(jsonString);
                    }
                }
            }
            catch (IOException e){
                Log.e("PROXIMITY SENSOR", e.getMessage());
            }
        }

        private void syncWifiData(String dataJSONString) throws IOException{
            if(db.getWifiCount()>0){
                List<DBHelper.WifiData> list = db.getAllWifiData();
                List<String> strList  = new ArrayList<>();
                for(DBHelper.WifiData w: list){
                    strList.add(getJSONString(w));
                }
                strList.add(dataJSONString);
                updateCloud("/wifidevices", getJSONString(strList));
                db.deleteAllWifiData();
            }
            else{
                updateCloud("/wifidevices", dataJSONString);
            }
        }


        @Override
        public void onDestroy() {
            Log.v("PROXIMITY SENSOR", "STOPPING WIFI SENSOR");
            mTimer.cancel();
            mTimer.purge();
            super.onDestroy();
        }
    }


    public static class GeolocationService extends Service implements LocationListener{


        private final static int DEFAULT_VALUE = -1;
        private String deviceId;
        boolean isGPSEnable = false;
        boolean isNetworkEnable = false;
        double latitude,longitude;
        LocationManager locationManager;
        Location location;
        Location plocation;
        private Handler mHandler = new Handler();
        private Timer mTimer = null;
        long notify_interval = 15000;


        public GeolocationService(){

        }


        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }


        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            try{
                Log.v("PROXIMITY SENSOR", "STARTING GEOLOCATION SEVICE");
                mTimer = new Timer();
                mTimer.schedule(new TimerTaskToGetLocation(),5,notify_interval);
            }
            catch (Exception e){
                Log.e("PROXIMITY SENSOR", e.getMessage());
            }
            return super.onStartCommand(intent, flags, startId);
        }



        @Override
        public void onLocationChanged(Location location) {

        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }




        private void fn_getlocation(){
            locationManager = (LocationManager)getApplicationContext().getSystemService(LOCATION_SERVICE);
            isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
            if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
                    android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                Log.v("PROXIMITY SENSOR", "SCANNING GEOLOCATION PERMISSION");
                Intent intent = new Intent(SENSOR_REQUEST_PERMISSIONS);
                return;
            }
            if (!isGPSEnable && !isNetworkEnable){
                Log.v("PROXIMITY SENSOR", "GEOLOCATION GPS AND NETWORK HARDWARE SWITCHED OFF");
                Intent intent = new Intent(GEOLOCATION_SETTINGS_ACTION);
                context.sendBroadcast(intent);
            }else {
                Log.v("PROXIMITY SENSOR", "SCANNING GEOLOCATION");
                if (isGPSEnable){
                    Log.v("PROXIMITY SENSOR", "SCANNING GEOLOCATION WITH GPS");
                    location = null;;
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,0,this);
                    if (locationManager!=null){
                        location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location!=null){
                            Log.e("latitude",location.getLatitude()+"");
                            Log.e("longitude",location.getLongitude()+"");
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                            checkChangesAndUpdate(location);
                        }
                    }
                }
                else if (isNetworkEnable){
                    Log.v("PROXIMITY SENSOR", "SCANNING GEOLOCATION WITH NETWORK HARDWARE");
                    location = null;
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000,0,this);
                    if (locationManager!=null){
                        location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location!=null){

                            Log.e("latitude",location.getLatitude()+"");
                            Log.e("longitude",location.getLongitude()+"");

                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                            checkChangesAndUpdate(location);
                        }
                    }
                }


            }

        }

        private class TimerTaskToGetLocation extends TimerTask {
            @Override
            public void run() {

                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.v("PROXIMITY SENSOR","GETTING GEOLOCATION");
                        fn_getlocation();
                    }
                });

            }
        }

        private boolean isLocationEqual(Location location1, Location location2){
            return location1.equals(location2);
        }

        private void checkChangesAndUpdate(Location location){
            Log.v("PROXIMITY SENSOR", "GEOLOCATION DATA COMPARISON: "+isLocationEqual(location, plocation));
            Log.v("PROXIMITY SENSOR", "GEOLOCATION DATA :"+location);
            if(!isLocationEqual(location, plocation)){
                plocation = location;
                updateGeolocation(location);
            }
        }

        private void updateGeolocation(Location location){
            try{
                String jsonString  = getJSONString(location);
                if(!jsonString.trim().isEmpty()){
                    if(!networkAvailable(this)){
                        updateLocal("GEOLOCATION", jsonString);
                    }
                    else{
                        syncGeolocationData(jsonString);
                    }
                }
            }
            catch (IOException e){
                Log.e("PROXIMITY SENSOR", e.getMessage());
            }
        }



        private void syncGeolocationData(String dataJSONString) throws IOException{
            if(db.getWifiCount()>0){
                List<DBHelper.GeolocationData> list = db.getAllGeolocationData();
                List<String> strList  = new ArrayList<>();
                for(DBHelper.GeolocationData w: list){
                    strList.add(getJSONString(w));
                }
                strList.add(dataJSONString);
                updateCloud("/geolocations", getJSONString(strList));
                db.deleteAllGeolocationData();
            }
            else{
                updateCloud("/geolocations", dataJSONString);
            }
        }


        @Override
        public void onDestroy() {
            Log.v("PROXIMITY SENSOR", "DESTROING GEOLOCATION SERVICE");
            mTimer.cancel();
            mTimer.purge();
            super.onDestroy();
        }
    }


    public static class WifiP2PService extends Service{


        public WifiP2PService(){

        }



        public class WifiP2PBroadcastReceiver extends BroadcastReceiver{


            private IntentFilter getIntentFilter(){
                IntentFilter intentFilter = new IntentFilter();
                intentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
                intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
                intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
                return intentFilter;
            }


            public void registerReceiver(Context context){
                IntentFilter intentFilter = getIntentFilter();
                context.registerReceiver(this, intentFilter);
            }

            @Override
            public void onReceive(Context context, Intent intent) {
                allocateTask(intent);
            }
        }



        private void allocateTask(Intent intent){
            String action = intent.getAction();
            try {
                if(action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)){
                    onStateChangedAction(intent);
                }
                else if(action.equals(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION)){
                    onDiscoveryChangedAction(intent);
                }
                else if(action.equals(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION)){
                    onPeersChangedAction(intent);
                }
            }
            catch (NullPointerException e){
                Log.e("SENSORSERVICE", e.getMessage());
            }
        }



        private WifiP2pManager wifiP2pManager;
        private WifiP2pManager.Channel channel;
        private List<WifiP2pDevice> pList;
        private WifiP2PBroadcastReceiver broadcastReceiver;
        private Timer mTimer;
        private int notify_interval=20000;
        private Handler mHandler = new Handler();


        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.v("PROXIMITY SENSOR", "STARTING WIFIDIRECT SERVICE");
            this.broadcastReceiver = new WifiP2PBroadcastReceiver();
            this.broadcastReceiver.registerReceiver(this);
            this.pList = new ArrayList<>();
            this.wifiP2pManager = (WifiP2pManager) context.getSystemService(Context.WIFI_P2P_SERVICE);
            this.channel = this.wifiP2pManager.initialize(this, this.getMainLooper(), null);
            mTimer = new Timer();
            mTimer.schedule(new TimerTaskToGetLocation(),5,notify_interval);
            return super.onStartCommand(intent, flags, startId);
        }

        @Nullable @Override
        public IBinder onBind(Intent intent) {
            return null;
        }

        private class TimerTaskToGetLocation extends TimerTask {
            @Override
            public void run() {

                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.v("PROXIMITY SENSOR", "GETTING PEER DEVICES");
                        wifiP2pManager.discoverPeers(channel, null);
                        wifiP2pManager.requestPeers(channel, peerListListener);
                    }
                });

            }
        }


        private void onStateChangedAction(Intent intent){
            if(intent.hasExtra(WifiP2pManager.EXTRA_WIFI_STATE)){
                int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
                if(state == WifiP2pManager.WIFI_P2P_STATE_ENABLED){

                }
                else if(state == WifiP2pManager.WIFI_P2P_STATE_DISABLED){

                }
            }
        }


        private void onDiscoveryChangedAction(Intent intent){
            if(intent.hasExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE)){
                int state = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, -1);
                if(state == (WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED)){
                    onPeersDiscoveryStarted(intent);
                }
                else if(state == (WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED)){
                    onPeersDiscoveryStopped(intent);
                }
            }
        }

        private void onPeersChangedAction(Intent intent){
            Log.v("PROXIMITY SENSOR","WIFIDIRECT SERVICE PEER CHANGED ACTION");
            if(intent.hasExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST)){
                onPeersAvailable(intent);
            }
        }


        private void onPeersDiscoveryStarted(Intent intent){
            Log.v("PROXIMITY SENSOR","PEER DISCOVERY STARTED ACTION");
        }

        private void onPeersDiscoveryStopped(Intent intent){
            Log.v("PROXIMITY SENSOR", "PEER DISCOVERY STOPPED ACTION");
        }


        private void onPeersAvailable(Intent intent){
            Log.v("PROXIMITY SENSOR", "PEERS DEVICE AVAILABLE");
            this.requestPeers(intent);
        }

        private void requestPeers(Intent intent){
            WifiP2pDeviceList wifiP2pDeviceList = intent.getParcelableExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST);
            Collection<WifiP2pDevice> dList = wifiP2pDeviceList.getDeviceList();
            List<WifiP2pDevice> deviceList = new ArrayList<>();
            deviceList.addAll(dList);
            checkChangesAndUpdate(deviceList);
        }


        WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
            @Override
            public void onPeersAvailable(WifiP2pDeviceList wifiP2pDeviceList) {
                Collection<WifiP2pDevice> dList = wifiP2pDeviceList.getDeviceList();
                List<WifiP2pDevice> deviceList = new ArrayList<>();
                deviceList.addAll(dList);
                checkChangesAndUpdate(deviceList);
            }
        };

        private boolean isDeviceListEqual(List<WifiP2pDevice> list1, List<WifiP2pDevice> list2){
            return list1.equals(list2);
        }



        private void checkChangesAndUpdate(List<WifiP2pDevice> deviceList){
            Log.v("PROXIMITY SENSOR","WIFIDIRECT RESULTS: "+deviceList.toString());
            if(!isDeviceListEqual(deviceList, pList)){
                pList = deviceList;
                updateWifiP2PDevices(deviceList);
            }
        }

        private void updateWifiP2PDevices(Collection<WifiP2pDevice> deviceList){
            try{
                String jsonString  = getJSONString(deviceList);
                if(!jsonString.trim().isEmpty()){
                    if(!networkAvailable(this)){
                        updateLocal("WIFIDIRECT", jsonString);
                    }
                    else{
                        syncWifiP2PData(jsonString);
                    }
                }
            }
            catch (IOException e){
                Log.d("PROXIMITY SENSOR", e.getMessage());
            }
        }



        private void syncWifiP2PData(String dataJSONString) throws IOException{
            if(db.getWifiCount()>0){
                List<DBHelper.GeolocationData> list = db.getAllGeolocationData();
                List<String> strList  = new ArrayList<>();
                for(DBHelper.GeolocationData w: list){
                    strList.add(getJSONString(w));
                }
                strList.add(dataJSONString);
                updateCloud("/peer_devices", getJSONString(strList));
                db.deleteAllWifiP2PData();
            }
            else{
                updateCloud("/peer_devices", dataJSONString);
            }
        }




        @Override
        public void onDestroy() {
            this.wifiP2pManager.stopPeerDiscovery(channel, null);
            this.unregisterReceiver(this.broadcastReceiver);
            mTimer.cancel();
            mTimer.purge();
            super.onDestroy();
        }
    }
}
