package cn.tee3.avd;
/**
 * Created by bob.liu on 2015/8/24.
 */

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.annotation.Nullable;

class NetworkProber {
  private static final String TAG = "NetworkProber";

  public enum  Status{
    Network_Wifi_Actived,
    Network_Mobile_Actived,
    Network_Diconnected
  }
  public interface Listener {
    void onNetworkChanged(Status status);
  }

  private static NetworkProber _networkProber;
  public static NetworkProber instance() {
    if (null == _networkProber) {
      _networkProber = new NetworkProber();
    }
    return _networkProber;
  }
  private boolean isEnable = true;
  public boolean isEnable() {
    return isEnable;
  }
  public void enable(boolean enable) {
    if (isEnable == enable) {
      return ;
    }
    isEnable = enable;
    if (isEnable) {
      init(_context);
    }
    else {
      unInit();
    }
  }
  public boolean init(Context context) {
    if (null != _context || null == context) {
      Tlog.w(TAG, "init, invalid arg or context has init. this.context="+_context + ",context="+context);
      return false;
    }
    Tlog.i(TAG, "init, context="+context+",_listeners="+((null ==_listeners) ? 0 : _listeners.size()));
    _context = context;
    if (!isEnable) {
      return true;
    }
    if (null == _listeners) {
      _listeners = new LinkedList<Listener>();
    }
    _receiver = new ConnectivityChangeReceiver();
    _intent = _context.registerReceiver(_receiver, FILTER);
    _netStatus = getNetworkStatus(_context);
    return true;
  }
  public boolean unInit() {
    Tlog.i(TAG, "unInit, _context=" + _context + ",_receiver=" + _receiver);

    if (null != _context && null != _receiver) {
      _context.unregisterReceiver(_receiver);
    }
    if (null != _listeners) {
      synchronized (_listeners) {
        _listeners.clear();
      }
    }
   // _context = null;
    _intent = null;
    _receiver = null;
    return true;
  }
  Context _context;
  @Nullable Intent _intent;
  @Nullable ConnectivityChangeReceiver  _receiver;
  List<Listener> _listeners;
  public boolean registerReceiver(Listener receiver) {
    Tlog.v(TAG, "registerReceiver, receiver="+receiver);
    if (null == _listeners) {
      return false;
    }
    synchronized (_listeners) {
      _listeners.add(receiver);
    }
    return true;
  }
  public boolean unregisterReceiver(Listener receiver) {
    Tlog.v(TAG, "unregisterReceiver, receiver="+receiver);
    if (null == _listeners) {
      return false;
    }
    synchronized (_listeners) {
      _listeners.remove(receiver);
    }
    return true;
  }

  private Status getNetworkStatus(Context context) {
    if (null == context) {
      return Status.Network_Diconnected;
    }
    this._wifiNameChanged = false;
    ConnectivityManager cm = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    if (null == cm) {
      Tlog.e(TAG, "getNetworkStatus, getSystemService failed.");
      return Status.Network_Diconnected;
    }
    NetworkInfo info = cm.getActiveNetworkInfo();
    if (null == info) {
      //Tlog.e(TAG, "getNetworkStatus, getActiveNetworkInfo failed.");
      return Status.Network_Diconnected;
    }
    if (!info.isConnected()) {
      return Status.Network_Diconnected;
    }
    if (ConnectivityManager.TYPE_WIFI == info.getType()) {
      if (null != _wificurName) {
        this._wifiNameChanged = ! _wificurName.equalsIgnoreCase(info.getExtraInfo());
      }
      _wificurName = info.getExtraInfo();
      return Status.Network_Wifi_Actived;
    }
    if (ConnectivityManager.TYPE_MOBILE == info.getType()) {
      return Status.Network_Mobile_Actived;
    }
    Tlog.w(TAG, "getNetworkStatus, type="+info.toString());
    return Status.Network_Diconnected;
  }

  Status _netStatus;
  boolean _wifiNameChanged = false;
  String _wificurName;
  private static final IntentFilter FILTER = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
  public class ConnectivityChangeReceiver extends BroadcastReceiver {
    @Override
    public final void onReceive(Context context, Intent intent) {
      //Tlog.v(TAG, "onReceive, intent="+intent.toString());
      Status curStatus = getNetworkStatus(context);
      //Tlog.v(TAG, "onReceive, old="+_netStatus+",new="+curStatus + ",intent="+intent.toString());
      if (_netStatus != curStatus
              || (Status.Network_Wifi_Actived == _netStatus && _wifiNameChanged)) {
        _netStatus = curStatus;
        synchronized (_listeners) {
          Iterator<Listener> it = _listeners.iterator();
          while (it.hasNext()) {
            Listener cb = it.next();
            cb.onNetworkChanged(_netStatus);
          }
        } //synchronized
      }
    } //onReceive
  } //ConnectivityChangeReceiver
}
