package in.futuretech.android.reportbatterycharge;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.BatteryManager;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ReportChargeService extends Service {
    private final BroadcastReceiver batteryChargeBroadcastReceiver = new BatteryChargeBroadcastReceiver(this);
    private static final String logTag = ReportChargeService.class.getSimpleName();

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        Log.i(logTag, "Service started");

        IntentFilter batteryChangedFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent batteryStatus = registerReceiver(batteryChargeBroadcastReceiver, batteryChangedFilter);

        reportBatteryState(batteryStatus);

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        // TODO: Can this identifier be saved in a location accessible from both manifest and here?
        Intent restartIntent = new Intent("in.futuretech.android.reportbatterycharge.RESTART_SERVICE");
        sendBroadcast(restartIntent);
        unregisterReceiver(batteryChargeBroadcastReceiver);

        Log.i(logTag, "Service destroyed");
        super.onDestroy();
    }

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

    private void reportBatteryState(Intent intent) {
        ReportChargeTaskParams taskParams = new ReportChargeTaskParams(intent, getDeviceId());
        Log.i(logTag, "Current charge level: " + taskParams.ChargePercent + " (" + (taskParams.IsCharging ? "" : "NOT ") + "charging)");

        new ReportChargeTask().execute(taskParams);
    }

    @SuppressLint("HardwareIds")
    private String getDeviceId() {
        // To identify the device when multiple devices are reporting to the same service
        return Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
    }

    private class BatteryChargeBroadcastReceiver extends BroadcastReceiver {
        private final ReportChargeService reportChargeService;

        public BatteryChargeBroadcastReceiver(ReportChargeService reportChargeService) {
            this.reportChargeService = reportChargeService;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            reportChargeService.reportBatteryState(intent);
        }
    }

    private final class ReportChargeTaskParams {
        ReportChargeTaskParams(Intent intent, String deviceId) {
            DeviceId = deviceId;
            int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
            IsCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                    status == BatteryManager.BATTERY_STATUS_FULL;

            int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

            ChargePercent = level / (float) scale;
        }

        final float ChargePercent;
        final boolean IsCharging;
        final String DeviceId;
    }

    private class ReportChargeTask extends AsyncTask<ReportChargeTaskParams, Void, Void> {

        @Override
        protected Void doInBackground(ReportChargeTaskParams... params) {
            ReportChargeTaskParams actualParams = params[0];

            try {
                URL url = new URL("http://192.168.2.5/report-charge/report.php?charge="
                        + actualParams.ChargePercent + "&charging=" + actualParams.IsCharging);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                try {
                    int responseCode = connection.getResponseCode();
                    if (responseCode < 200) {
                        Log.w(logTag, "Report service unexpected response code: " + responseCode);
                    } else if (responseCode < 400) {
                        Log.i(logTag, "Report service response code: " + responseCode);
                    } else {
                        Log.w(logTag, "Report service error code: " + responseCode);
                    }
                } finally {
                    connection.disconnect();
                }
            } catch (MalformedURLException e) {
                Log.w(logTag, "Report service call failed: Invalid URL");
            } catch (IOException e) {
                Log.w(logTag, "Report service call failed: I/O error");
            }

            return null;
        }
    }
}

@@ -528,16 +528,41 @@
 et.URL;%0A
+import java.util.Locale;%0A
 import j
@@ -2025,16 +2025,30 @@
 logTag, 
+String.format(
 %22Current
@@ -2062,19 +2062,35 @@
  level: 
-%22 +
+%25f (Charging: %25b)%22,
  taskPar
@@ -2110,19 +2110,10 @@
 cent
+,
  
-+ %22 (%22 + (
 task
@@ -2133,37 +2133,9 @@
 ging
- ? %22%22 : %22NOT %22) + %22charging)%22
+)
 );%0A%0A
@@ -3903,131 +3903,318 @@
 URL(
-%22http://192.168.2.5/report-charge/report.php?charge=%22%0A                        + actualParams.ChargePercent + %22&charging=%22 +
+%0A                        String.format((Locale)null,%0A                                %22http://192.168.2.5/report-charge/report.php?device=%25s&charge=%25f&charging=%25b%22,%0A                                actualParams.DeviceId,%0A                                actualParams.ChargePercent,%0A                               
  act
@@ -4234,17 +4234,19 @@
 harging)
-;
+);%0A
 %0A       
@@ -4494,32 +4494,46 @@
   Log.w(logTag, 
+String.format(
 %22Report service 
@@ -4550,35 +4550,36 @@
  response code: 
-%22 +
+%25d%22,
  responseCode);%0A
@@ -4568,32 +4568,33 @@
 %22, responseCode)
+)
 ;%0A              
@@ -4662,32 +4662,46 @@
   Log.i(logTag, 
+String.format(
 %22Report service 
@@ -4711,27 +4711,28 @@
 ponse code: 
-%22 +
+%25d%22,
  responseCod
@@ -4725,32 +4725,33 @@
 %22, responseCode)
+)
 ;%0A              
@@ -4795,32 +4795,46 @@
   Log.w(logTag, 
+String.format(
 %22Report service 
@@ -4849,11 +4849,12 @@
 de: 
-%22 +
+%25d%22,
  res
@@ -4863,16 +4863,17 @@
 nseCode)
+)
 ;%0A      

Add some more String.format(), send device ID to service