/*
 * COPYRIGHT (c) 2018 All rights reserved by HANWHA LIFE.
 */
package kr.co.zumo.app.lifeplus.network;

import android.content.Context;
import android.util.Log;

import io.reactivex.Observable;
import io.reactivex.Single;
import kr.co.zumo.app.lifeplus.config.NetworkConfig;
import kr.co.zumo.app.lifeplus.util.NetworkUtil;

/**
 * NetworkWatcher
 * <pre>
 * </pre>
 *
 * @author 민효동
 * @version 1.0
 * @history 민효동   [2018. 9. 19.]   [최초 작성]
 * @since 2018. 9. 19.
 */
public class NetworkWatcher {

  /**
   * 네트워크 장치 연결과 인터넷 연결이 됐는지 확인한다.
   * - Single 을 반환하므로 subscribe 하여 boolean 값을 참고하여 진행한다.
   *
   * @param context
   * @return rx Single with Boolean
   */
  public static Single<Boolean> check(Context context) {
    return check(new NetworkStatus(NetworkUtil.getNetworkInfo(context)));
  }

  /**
   * 네트워크 장치 연결과 인터넷 연결이 됐는지 확인한다.
   * - Single 을 반환하므로 subscribe 하여 boolean 값을 참고하여 진행한다.
   *
   * @param networkStatus NetworkStatus
   * @return rx Single with Boolean
   */
  public static Single<Boolean> check(NetworkStatus networkStatus) {
    Single<Boolean> single;

    boolean isConnected = networkStatus.isConnected();

    if (isConnected) {
      single = InternetStatus.check(NetworkConfig.HOST_URL, NetworkConfig.HOST_PORT);
    }
    else {
      single = Single.fromCallable(() -> false);
    }

    return single;
  }

  /**
   * 네트워크 장치 연결과 인터넷 연결이 됐는지 감시한다.
   * - 변경이 있을 때 발행한다.
   *
   * @param context
   * @return rx Observable with Boolean
   */
  public static Observable<Boolean> watch(Context context) {

    // 네트워크 장치 연결 감시
    Observable<Boolean> network = NetworkReceiver.getObservable(context);

    // 인터넷 연결 감시
    Observable<Boolean> internet = InternetStatus.observe(NetworkConfig.HOST_URL, NetworkConfig.HOST_PORT, 2000, 1000);
//    Observable<Boolean> internet = InternetStatus.observe("google.com", 80, 2000, 1000);

    return watch(network, internet);
  }

  /**
   * 네트워크 장치 연결과 인터넷 연결이 됐는지 감시한다.
   * - 변경이 있을 때 발행한다.
   *
   * @param network
   * @param internet
   * @return rx Observable with Boolean
   */
  public static Observable<Boolean> watch(Observable<Boolean> network, Observable<Boolean> internet) {
    /**
     * 두 객체의 결과를 조합하여 변화가 있을 때만 발행함.
     */
    Observable<Boolean> watcher = Observable.combineLatest(network, internet, (isConnectedNetwork, isConnectedInternet) -> {
      Log.i("APP# ActivityBase | watchNetwork", "|" + " isConnected-Network: " + isConnectedNetwork);
      Log.i("APP# ActivityBase | watchNetwork", "|" + " isConnected-Internet: " + isConnectedInternet);
      return isConnectedNetwork && isConnectedInternet;
    }).distinctUntilChanged();

    return watcher;
  }
}
