package com.cerveza.togglefunction;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.telephony.CellInfo;
import android.util.Log;

import com.cerveza.togglefunction.api.ControlFunction;
import com.cerveza.togglefunction.api.EMessageType;
import com.cerveza.togglefunction.serializeutil.SerializeUtils;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import static com.cerveza.togglefunction.api.EMessageType.AUDIO_CHANGE_STATUS;
import static com.cerveza.togglefunction.api.EMessageType.BLUETOOTH_CHANGE_STATUS;
import static com.cerveza.togglefunction.api.EMessageType.FUNCTIONS_STATE_INITIALIZE;
import static com.cerveza.togglefunction.api.EMessageType.FUNCTIONS_STATE_SYNCHRONIZATION;
import static com.cerveza.togglefunction.api.EMessageType.GET_WIFI_INFO;
import static com.cerveza.togglefunction.api.EMessageType.GPS_CHANGE_STATUS;
import static com.cerveza.togglefunction.api.EMessageType.MOBILE_DATA_CHANGE_STATUS;
import static com.cerveza.togglefunction.api.EMessageType.WIFI_CHANGE_STATUS;

/**
 * Created by cerveza on 04/02/2017.
 */

public class ToggleFunctionServer extends Service {

    private FunctionChangeHandler functionChangeHandler;
    //private MessageSendService messageSendService;
    //private boolean messageSendServiceBound;

    BroadcastReceiver functionChangereceiver;
    BatteryStatusReceiver batteryStatusReceiver;

    private Timer timer;
    private TimerTask timerTask;
    Date nextExecutionTime;
    private static final long STOP_TIME = 1 * 60 * 1000 ; //after this time the service will stop (miliseconds)



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

        if(intent.getAction() == "WEARABLE_COMMAND"){
            restartTimerIfNecessary();
        }

        if (intent.getAction() == "WEARABLE_COMMAND" || intent.getAction() == "SERVICE_COMMAND") {
            String path = (String) intent.getExtras().get("MESSAGE_PATH");
            if(path.equalsIgnoreCase(WIFI_CHANGE_STATUS.getPath())){
                functionChangeHandler.changeWifiStatus();
            }else if(path.equalsIgnoreCase(BLUETOOTH_CHANGE_STATUS.getPath())){
                functionChangeHandler.changeBluetoothState();
            }else if (path.equalsIgnoreCase(GPS_CHANGE_STATUS.getPath())){
                functionChangeHandler.changeGPSStatus();
            }else if(path.equalsIgnoreCase(MOBILE_DATA_CHANGE_STATUS.getPath())){
                functionChangeHandler.changeMobileDataStatus();
            }else if(path.equalsIgnoreCase(FUNCTIONS_STATE_SYNCHRONIZATION.getPath())){
                functionSynchronization();
            }else if(path.equalsIgnoreCase(FUNCTIONS_STATE_INITIALIZE.getPath())){
                functionStateInitzialize();
            }else if(path.equalsIgnoreCase(GET_WIFI_INFO.getPath())){
                functionGetWifiInfo();
            }else if(path.equalsIgnoreCase(AUDIO_CHANGE_STATUS.getPath())){
                functionChangeHandler.changeAudioStatus();
            }
        }

        return START_STICKY;
    }

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

    @Override
    public void onCreate() {
        super.onCreate();
        functionChangereceiver = new FunctionChangeReceiver();
        batteryStatusReceiver = new BatteryStatusReceiver();
        functionChangeHandler =  new FunctionChangeHandler(this);
        timer = new Timer();
        //bindServices();
        registerReceivers();
        initTimerTask();
        scheduleTask();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //unbindServices();
        unregisterReceivers();
    }

    private void functionSynchronization() {
        List<ControlFunction> controls = functionChangeHandler.getUpdatedControls();
        if (controls.size() > 0) {
                sendMessage(FUNCTIONS_STATE_SYNCHRONIZATION.getPath(), serialize(controls));

        }
    }

    private void functionStateInitzialize() {
        functionChangeHandler.resetControls();
        List<ControlFunction> controls = functionChangeHandler.getUpdatedControls();
        if (controls.size() > 0) {
            sendMessage(EMessageType.FUNCTIONS_STATE_INITIALIZE.getPath(), serialize(controls) );
            }
        }


    private void functionGetWifiInfo() {
        sendMessage(GET_WIFI_INFO.getPath(), serialize(functionChangeHandler.getWifiInfo()));
    }


    //--------------------receiver-------------------------------------------------
    private void registerReceivers(){
        IntentFilter intentFilterFunctionChange = new IntentFilter();
        for (String item : FunctionChangeReceiver.INTENT_FILTER_ARRAY) {
            intentFilterFunctionChange.addAction(item);
        }
        registerReceiver(functionChangereceiver, intentFilterFunctionChange);

        Intent intent = registerReceiver(batteryStatusReceiver, BatteryStatusReceiver.ifilter);
        batteryStatusReceiver.onReceive(this, intent);
    }

    private void unregisterReceivers(){
        unregisterReceiver(functionChangereceiver);
        unregisterReceiver(batteryStatusReceiver);
    }

    //--------------------timer-----------------------------------------------------
    private void initTimerTask(){
        timerTask = new TimerTask() {
            @Override
            public void run() {
                stopSelf();
            }
        };
    }

    private  void scheduleTask(){
        nextExecutionTime = new Date(Calendar.getInstance().getTimeInMillis()+STOP_TIME);
        timer.schedule(timerTask, nextExecutionTime );
    }

    public void restartTimerIfNecessary(){
        if( (nextExecutionTime.getTime() - Calendar.getInstance().getTimeInMillis()) < (STOP_TIME / 2)){
            timerTask.cancel();
            timer.purge();
            initTimerTask();
            scheduleTask();
        }
    }

    //-----------------binding------------------------------------------------------
   /* private ServiceConnection messageSendConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            MessageSendService.MessageSendBinder binder = (MessageSendService.MessageSendBinder) service;
            messageSendService = binder.getService();
            messageSendServiceBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            messageSendServiceBound = false;
        }
    };

    private void bindServices() {
        Intent intent = new Intent(this, MessageSendService.class);
        bindService(intent, messageSendConnection, this.BIND_AUTO_CREATE);

    }

    private void unbindServices() {
        unbindService(messageSendConnection);
    }*/

    public void sendMessage(String path, byte[] data){
        Intent intent = new Intent(this,MessageSendService.class).setAction("SEND_MESSAGE").
                putExtra("MESSAGE_PATH",path).putExtra("BYTES",data);
        this.startService(intent);
    }

    public byte[] serialize (Object object){
        byte[] bytes;
        try {
            bytes = SerializeUtils.convertToBytes(object);
            return bytes;
        } catch (IOException e) {
            Log.e(getClass().getName(),"IO exeption during converting from object to bytes",e);
        }
        return null;
    }

}
