package com.eaze.locationbackgroundtimer.connectivity;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellSignalStrengthGsm;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * Helper class for monitoring network connectivity changes
 */

public class ConnectivityUtil {
    private static final String TAG = ConnectivityUtil.class.getSimpleName();

    public static int TYPE_CONNECTED = 1;
    public static int TYPE_NOT_CONNECTED = 0;

    private static final String TYPE_WIFI = "WIFI";
    private static final String TYPE_NETWORK = "NETWORK";
    private static final String TYPE_NONE = "NONE";

    public static int getConnectivityStatus(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (null != activeNetwork) {
            int type = activeNetwork.getType();
            if (type == ConnectivityManager.TYPE_WIFI || type == ConnectivityManager.TYPE_MOBILE) {
                return TYPE_CONNECTED;
            }
        }
        return TYPE_NOT_CONNECTED;
    }

    public static String getConnectivityType(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (activeNetwork == null) {
            return TYPE_NONE;
        }
        int type = activeNetwork.getType();
        switch (type) {
            case ConnectivityManager.TYPE_WIFI:
                return TYPE_WIFI;
            case ConnectivityManager.TYPE_MOBILE:
                return TYPE_NETWORK;
            default:
                return TYPE_NONE;
        }
    }

    public static String getSSID(Context context) {
        if (getConnectivityType(context).equals(TYPE_WIFI)) {
            final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
            if (connectionInfo != null && !TextUtils.isEmpty(connectionInfo.getSSID())) {
                return connectionInfo.getSSID();
            }
        }
        return null;
    }

    public static ArrayList<ConnectivityStrength> getSignalStrength(Context context) {
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        int levelCdma, levelGsm, levelLte, levelWcdma;
        ArrayList<ConnectivityStrength> connectivityStrengths = new ArrayList<>();
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
            List<CellInfo> cellInfoList = telephonyManager.getAllCellInfo();
            if (cellInfoList != null) {
                Log.d(TAG, "cellInfoList size = " + cellInfoList.size());
                for (CellInfo cellInfo : cellInfoList) {
                    if (cellInfo instanceof CellInfoGsm) {
                        levelGsm = ((CellInfoGsm) cellInfo).getCellSignalStrength().getLevel();
                        connectivityStrengths.add(new ConnectivityStrength(levelGsm, cellInfo));
                    } else if (cellInfo instanceof CellInfoLte) {
                        levelLte = ((CellInfoLte) cellInfo).getCellSignalStrength().getLevel();
                        connectivityStrengths.add(new ConnectivityStrength(levelLte, cellInfo));
                    } else if (cellInfo instanceof CellInfoCdma) {
                        levelCdma = ((CellInfoCdma) cellInfo).getCellSignalStrength().getLevel();
                        connectivityStrengths.add(new ConnectivityStrength(levelCdma, cellInfo));
                    } else if (cellInfo instanceof CellInfoCdma) {
                        levelWcdma = ((CellInfoCdma) cellInfo).getCellSignalStrength().getLevel();
                        connectivityStrengths.add(new ConnectivityStrength(levelWcdma, cellInfo));
                    }
                }
            }
        }
        return connectivityStrengths;
    }

    public static class ConnectivityStrength implements Parcelable {
        private int mLevel;
        private String mType;

        public ConnectivityStrength(int level, CellInfo cellInfo) {
            mLevel = level;
            mType = cellInfo.getClass().getSimpleName();
        }

        protected ConnectivityStrength(Parcel in) {
            mLevel = in.readInt();
            mType = in.readString();
        }

        public static final Creator<ConnectivityStrength> CREATOR = new Creator<ConnectivityStrength>() {
            @Override
            public ConnectivityStrength createFromParcel(Parcel in) {
                return new ConnectivityStrength(in);
            }

            @Override
            public ConnectivityStrength[] newArray(int size) {
                return new ConnectivityStrength[size];
            }
        };

        @Override
        public String toString() {
            return "Type=" + mType + ",Level=" + mLevel;
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(mLevel);
            dest.writeString(mType);
        }
    }
}
