package com.cerveza.togglefunction;

import android.app.IntentService;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import com.cerveza.togglefunction.serializeutil.SerializeUtils;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.MessageApi;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * Created by cerveza on 16/11/2016.
 */

public class MessageSendService extends IntentService implements GoogleApiClient.ConnectionCallbacks {
    private static GoogleApiClient mApiClient;
    private final IBinder mBinder = new MessageSendBinder();

    public MessageSendService() {
        super("message send service");
    }


    @Override
    public void onCreate() {
        if (mApiClient==null){
            initGoogleApiClient();
        }
        if(!mApiClient.isConnected()){
            mApiClient.connect();
        }

        super.onCreate();
    }

    public class MessageSendBinder extends Binder {
        MessageSendService getService() {
            return MessageSendService.this;
        }
    }


    @Override
    public void onConnected(Bundle bundle) {

        Log.i(getClass().getName(),"connected to api");
    }

    @Override
    public void onConnectionSuspended(int i) {

    }



    private void initGoogleApiClient() {
        mApiClient = new GoogleApiClient.Builder( this )
                .addApi( Wearable.API )
                .build();

        mApiClient.connect();
    }

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

    @Override
    protected void onHandleIntent(Intent intent) {
        if("SEND_MESSAGE".equals(intent.getAction())){
            byte[] bytes = intent.getByteArrayExtra("BYTES");
            String messagePath = (String) intent.getExtras().get("MESSAGE_PATH");

            if(mApiClient.blockingConnect(10, TimeUnit.SECONDS).isSuccess()){
                new SendToDataLayerThread(messagePath,bytes).start();
            }
        }

    }

    public <T> void  sendMessage(String path, T data){
        byte[] bytes = null;
        if(!(data instanceof byte[])){
            try {
                bytes = SerializeUtils.convertToBytes(data);
            } catch (IOException e) {
                Log.e(this.getClass().getName(), "could not parse object to bytes", e);
            }
        }else{
            bytes = (byte[]) data;
        }

        if(mApiClient.isConnected()){
            new SendToDataLayerThread(path,bytes).start();
        }
    }

    private class SendToDataLayerThread extends Thread {
        String path;
        byte[] data;

        SendToDataLayerThread(String path, String data) {
            this.path = path;
            this.data = data.getBytes();
        }

        SendToDataLayerThread(String path, byte[] data) {
            this.path = path;
            this.data = data;
        }

        public void run() {
            NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mApiClient).await();
            for (Node node : nodes.getNodes()) {
                MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage(mApiClient, node.getId(), path, data).await();
                if (result.getStatus().isSuccess()) {
                    Log.v(this.getClass().getName(), "new message, path: {" + path + "} sent to: " + node.getDisplayName());
                } else {
                    Log.v(this.getClass().getName(), "ERROR: failed to send Message");
                }
            }
        }

    }
}