// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/Constants.java
// public class Constants {
// 
//     public static final String SCHEME_WEAR = "wear";
// 
//     // Message and Data paths
//     public static final String COMMAND_REQUEST_PATH = "/command/request";
//     public static final String COMMAND_RESPONSE_PATH = "/command/response";
//     public static final String CONFIG_PATH = "/config";
// 
//     // Shared timeout values
//     public static final int WEARABLE_CONN_TIMEOUT_MILLIS = 500;
//     public static final int GO_PRO_COMMAND_TIMEOUT_SEC = 5;
// 
//     public static final int TAKE_PHOTO = 10;
//     public static final int START_VIDEO = 20;
//     public static final int STOP_VIDEO = 21;
//     public static final int SWITCH_TO_PHOTO = 1;
//     public static final int SWITCH_TO_VIDEO = 2;
//     public static final int POWER_ON = 30;
//     public static final int POWER_OFF = 31;
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/GoProCommandRequest.java
// @AutoValue
// public abstract class GoProCommandRequest {
//     public abstract GoProCommand command();
//     public abstract long timestamp();
// 
//     public static GoProCommandRequest create(GoProCommand command, long timestamp) {
//         return new AutoValue_GoProCommandRequest(command, timestamp);
//     }
// 
//     public static JsonAdapter<GoProCommandRequest> jsonAdapter(Moshi moshi) {
//         return new AutoValue_GoProCommandRequest.MoshiJsonAdapter(moshi);
//     }
// 
//     public long id() {
//         return command() != null ? command().getId() : GoProCommand.UNKNOWN.getId();
//     }
// 
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/GoProCommandResponse.java
// @AutoValue
// public abstract class GoProCommandResponse {
//     public abstract long requestId();
//     public abstract boolean success();
//     @Nullable public abstract String message();
// 
//     public static GoProCommandResponse create(long requestId, boolean success, String message) {
//         return new AutoValue_GoProCommandResponse(requestId, success, message);
//     }
// 
//     public static JsonAdapter<GoProCommandResponse> jsonAdapter(Moshi moshi) {
//         return new AutoValue_GoProCommandResponse.MoshiJsonAdapter(moshi);
//     }
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/Constants.java
// public static final int GO_PRO_COMMAND_TIMEOUT_SEC = 5;
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/Constants.java
// public static final int WEARABLE_CONN_TIMEOUT_MILLIS = 500;


import android.os.Looper;
import android.support.annotation.NonNull;
import com.github.jbarr21.goproremote.common.data.Constants;
import com.github.jbarr21.goproremote.common.data.GoProCommandRequest;
import com.github.jbarr21.goproremote.common.data.GoProCommandResponse;
import com.google.android.gms.common.ConnectionResult;
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.Wearable;
import com.squareup.moshi.Moshi;
import com.twotoasters.servos.util.ListUtils;
import java.net.ConnectException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.functions.Func0;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
import timber.log.Timber;
import static com.github.jbarr21.goproremote.common.data.Constants.GO_PRO_COMMAND_TIMEOUT_SEC;
import static com.github.jbarr21.goproremote.common.data.Constants.WEARABLE_CONN_TIMEOUT_MILLIS;
        return !ListUtils.isEmpty(nodes)
            ? Observable.just(nodes.get(0).getId())
            : Observable.<String>error(new IllegalStateException("Unable to fetch peer id"));
    }

    private static Observable<Integer> sendCommandRequest(GoogleApiClient googleApiClient, String peerId, GoProCommandRequest commandRequest) {
        ensureGoogleApiClientConnected(googleApiClient);
        Timber.d("connectGoogleApiClient - sendCommandRequest? %b", Looper.myLooper() == Looper.getMainLooper());
        byte[] data = MOSHI.adapter(GoProCommandRequest.class).toJson(commandRequest).getBytes();
        int requestId = Wearable.MessageApi
                .sendMessage(googleApiClient, peerId, Constants.COMMAND_REQUEST_PATH, data)
                .await(GO_PRO_COMMAND_TIMEOUT_SEC, TimeUnit.SECONDS)
                .getRequestId();

        boolean requestSent = requestId != MessageApi.UNKNOWN_REQUEST_ID;
        Timber.d("GoPro command request sent = %b, apiClientConnected = %b", requestSent, googleApiClient.isConnected());
        return requestSent
                ? Observable.just(requestId)
                : Observable.<Integer>error(new Exception("Unable to send command message"));
    }

    public static Observable<Integer> sendGoProCommandResponse(GoogleApiClient googleApiClient, String peerId, GoProCommandResponse response) {
        ensureGoogleApiClientConnected(googleApiClient);
        Timber.d("connectGoogleApiClient - sendCommandRequest? %b", Looper.myLooper() == Looper.getMainLooper());
        byte[] data = MOSHI.adapter(GoProCommandResponse.class).toJson(response).getBytes();
        int responseRequestId = Wearable.MessageApi
                .sendMessage(googleApiClient, peerId, Constants.COMMAND_RESPONSE_PATH, data)
                .await(GO_PRO_COMMAND_TIMEOUT_SEC, TimeUnit.SECONDS)
                .getRequestId();

// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/Constants.java
// public class Constants {
// 
//     public static final String SCHEME_WEAR = "wear";
// 
//     // Message and Data paths
//     public static final String COMMAND_REQUEST_PATH = "/command/request";
//     public static final String COMMAND_RESPONSE_PATH = "/command/response";
//     public static final String CONFIG_PATH = "/config";
// 
//     // Shared timeout values
//     public static final int WEARABLE_CONN_TIMEOUT_MILLIS = 500;
//     public static final int GO_PRO_COMMAND_TIMEOUT_SEC = 5;
// 
//     public static final int TAKE_PHOTO = 10;
//     public static final int START_VIDEO = 20;
//     public static final int STOP_VIDEO = 21;
//     public static final int SWITCH_TO_PHOTO = 1;
//     public static final int SWITCH_TO_VIDEO = 2;
//     public static final int POWER_ON = 30;
//     public static final int POWER_OFF = 31;
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/GoProCommandRequest.java
// @AutoValue
// public abstract class GoProCommandRequest {
//     public abstract GoProCommand command();
//     public abstract long timestamp();
// 
//     public static GoProCommandRequest create(GoProCommand command, long timestamp) {
//         return new AutoValue_GoProCommandRequest(command, timestamp);
//     }
// 
//     public static JsonAdapter<GoProCommandRequest> jsonAdapter(Moshi moshi) {
//         return new AutoValue_GoProCommandRequest.MoshiJsonAdapter(moshi);
//     }
// 
//     public long id() {
//         return command() != null ? command().getId() : GoProCommand.UNKNOWN.getId();
//     }
// 
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/GoProCommandResponse.java
// @AutoValue
// public abstract class GoProCommandResponse {
//     public abstract long requestId();
//     public abstract boolean success();
//     @Nullable public abstract String message();
// 
//     public static GoProCommandResponse create(long requestId, boolean success, String message) {
//         return new AutoValue_GoProCommandResponse(requestId, success, message);
//     }
// 
//     public static JsonAdapter<GoProCommandResponse> jsonAdapter(Moshi moshi) {
//         return new AutoValue_GoProCommandResponse.MoshiJsonAdapter(moshi);
//     }
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/Constants.java
// public static final int GO_PRO_COMMAND_TIMEOUT_SEC = 5;
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/Constants.java
// public static final int WEARABLE_CONN_TIMEOUT_MILLIS = 500;


// Path: common/src/main/java/com/github/jbarr21/goproremote/common/utils/MessageUtils.java
import android.os.Looper;
import android.support.annotation.NonNull;
import com.github.jbarr21.goproremote.common.data.Constants;
import com.github.jbarr21.goproremote.common.data.GoProCommandRequest;
import com.github.jbarr21.goproremote.common.data.GoProCommandResponse;
import com.google.android.gms.common.ConnectionResult;
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.Wearable;
import com.squareup.moshi.Moshi;
import com.twotoasters.servos.util.ListUtils;
import java.net.ConnectException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.functions.Func0;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
import timber.log.Timber;
import static com.github.jbarr21.goproremote.common.data.Constants.GO_PRO_COMMAND_TIMEOUT_SEC;
import static com.github.jbarr21.goproremote.common.data.Constants.WEARABLE_CONN_TIMEOUT_MILLIS;

        return !ListUtils.isEmpty(nodes)
            ? Observable.just(nodes.get(0).getId())
            : Observable.<String>error(new IllegalStateException("Unable to fetch peer id"));
    }

    private static Observable<Integer> sendCommandRequest(GoogleApiClient googleApiClient, String peerId, GoProCommandRequest commandRequest) {
        ensureGoogleApiClientConnected(googleApiClient);
        Timber.d("connectGoogleApiClient - sendCommandRequest? %b", Looper.myLooper() == Looper.getMainLooper());
        byte[] data = MOSHI.adapter(GoProCommandRequest.class).toJson(commandRequest).getBytes();
        int requestId = Wearable.MessageApi
                .sendMessage(googleApiClient, peerId, Constants.COMMAND_REQUEST_PATH, data)
                .await(GO_PRO_COMMAND_TIMEOUT_SEC, TimeUnit.SECONDS)
                .getRequestId();

        boolean requestSent = requestId != MessageApi.UNKNOWN_REQUEST_ID;
        Timber.d("GoPro command request sent = %b, apiClientConnected = %b", requestSent, googleApiClient.isConnected());
        return requestSent
                ? Observable.just(requestId)
                : Observable.<Integer>error(new Exception("Unable to send command message"));
    }

    public static Observable<Integer> sendGoProCommandResponse(GoogleApiClient googleApiClient, String peerId, GoProCommandResponse response) {
        ensureGoogleApiClientConnected(googleApiClient);
        Timber.d("connectGoogleApiClient - sendCommandRequest? %b", Looper.myLooper() == Looper.getMainLooper());
        byte[] data = MOSHI.adapter(GoProCommandResponse.class).toJson(response).getBytes();
        int responseRequestId = Wearable.MessageApi
                .sendMessage(googleApiClient, peerId, Constants.COMMAND_RESPONSE_PATH, data)
                .await(GO_PRO_COMMAND_TIMEOUT_SEC, TimeUnit.SECONDS)
                .getRequestId();

        boolean responseSent = responseRequestId != MessageApi.UNKNOWN_REQUEST_ID;