package com.epson.mobilephone.common.wifidirect;

import android.app.Service;
import android.content.Context;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Build;
import android.os.HandlerThread;

import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Locale;

/**
 * 局域网wifi管理工具类
 */
public class WifiP2pUtils {

    private static final String TAG = "WifiP2pUtils";
    private static final int TIMEOUT_CONNECTIONINFO = 5000;
    private static WifiP2pUtils instance;
    private volatile WifiP2pGroup groupInfo = null;
    private HandlerThread handlerThread = null;
    private volatile Object lock = new Object();
    private Context mAppContext = null;
    private WifiP2pManager mWiFiP2PManager = null;
    private WifiP2pManager.Channel p2pChannnel = null;
    private volatile STATUS status = STATUS.IDLE;

    enum STATUS {
        IDLE,
        REQUEST_GROUPINFO
    }

    public static class ConnectionInfo {

        boolean isGroupOwnerThisDevice;
        public String p2PMacAdder;
        public String printerName;

        public ConnectionInfo() {
        }
    }

    /**
     * 新建实例
     *
     * @param context 上下文
     * @return
     */
    public static WifiP2pUtils getInstance(Context context) {
        WifiP2pUtils wifiP2pUtils = instance;
        if (wifiP2pUtils != null) {
            return wifiP2pUtils;
        }
        instance = new WifiP2pUtils(context);
        return instance;
    }

    private WifiP2pUtils(Context context) {
        if (Build.VERSION.SDK_INT >= 14) {
            mAppContext = context.getApplicationContext();
            handlerThread = new HandlerThread("Thread for WiFip2p");
            handlerThread.start();
            mWiFiP2PManager = (WifiP2pManager) mAppContext.getSystemService(Service.WIFI_P2P_SERVICE);
            WifiP2pManager wifiP2pManager = mWiFiP2PManager;
            if (wifiP2pManager != null) {
                p2pChannnel = wifiP2pManager.initialize(mAppContext, handlerThread.getLooper(), (WifiP2pManager.ChannelListener) null);
                if (this.p2pChannnel == null) {
                    mWiFiP2PManager = null;
                }
            }
        }
    }

    public boolean isConnectedWiFiP2P() {
        return getConnectionInfo() != null;
    }

    public ConnectionInfo getConnectionInfo() {
        WifiP2pDevice p2PPrinterInfo;
        WifiP2pGroup p2POwnerInfo = getP2POwnerInfo();
        if (p2POwnerInfo == null || (p2PPrinterInfo = getP2PPrinterInfo(p2POwnerInfo)) == null) {
            return null;
        }
        ConnectionInfo connectionInfo = new ConnectionInfo();
        connectionInfo.isGroupOwnerThisDevice = p2POwnerInfo.isGroupOwner();
        connectionInfo.p2PMacAdder = p2PPrinterInfo.deviceAddress;
        connectionInfo.printerName = p2PPrinterInfo.deviceName;
        return connectionInfo;
    }

    public WifiP2pDevice getP2PPrinterInfo(WifiP2pGroup wifiP2pGroup) {
        if (wifiP2pGroup == null) {
            return null;
        }
        if (!wifiP2pGroup.isGroupOwner() && wifiP2pGroup.getOwner() != null && PrimaryDeviceType.isPrinter(wifiP2pGroup.getOwner().primaryDeviceType)) {
            return wifiP2pGroup.getOwner();
        }
        for (WifiP2pDevice next : wifiP2pGroup.getClientList()) {
            if (PrimaryDeviceType.isPrinter(next.primaryDeviceType)) {
                return next;
            }
        }
        return null;
    }

    public NetworkInterface getP2PInterfaceInfo() {
        WifiP2pGroup p2POwnerInfo = getP2POwnerInfo();
        if (p2POwnerInfo == null) {
            return null;
        }
        try {
            return NetworkInterface.getByName(p2POwnerInfo.getInterface());
        } catch (SocketException e) {
            e.printStackTrace();
            return null;
        }
    }

    private WifiP2pGroup getP2POwnerInfo() {
        if (mWiFiP2PManager == null) {
            return null;
        }
        groupInfo = null;
        synchronized (this.lock) {
            status = STATUS.REQUEST_GROUPINFO;
            mWiFiP2PManager.requestGroupInfo(this.p2pChannnel, new WifiP2pManager.GroupInfoListener() {
                public void onGroupInfoAvailable(WifiP2pGroup wifiP2pGroup) {
                    WifiP2pGroup unused = groupInfo = wifiP2pGroup;
                    if (groupInfo != null) {
                        EPLog.d(WifiP2pUtils.TAG, "Received EXTRA_WIFI_P2P_GROUP = " + groupInfo.toString());
                    } else {
                        EPLog.d(WifiP2pUtils.TAG, "Received EXTRA_WIFI_P2P_GROUP = null");
                    }
                    resumeThread();
                }
            });
            try {
                lock.wait(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            status = STATUS.IDLE;
        }
        return groupInfo;
    }

    private void resumeThread() {
        synchronized (this.lock) {
            try {
                lock.notifyAll();
            } catch (IllegalMonitorStateException e) {
                e.printStackTrace();
            }
        }
    }

    public void disconnect() {
        WifiP2pManager wifiP2pManager = mWiFiP2PManager;
        if (wifiP2pManager != null) {
            wifiP2pManager.removeGroup(this.p2pChannnel, new WifiP2pManager.ActionListener() {
                public void onSuccess() {
                    EPLog.d(WifiP2pUtils.TAG, "Success removeGroup");
                }

                public void onFailure(int i) {
                    EPLog.d(WifiP2pUtils.TAG, "Failed removeGroup");
                }
            });
        }
    }

    public static class PrimaryDeviceType {
        private static final String DEMIRITA_WIFI_OUI = "0050F204";
        public static final int P2P_CATEGORY_PRINTER = 3;
        public static final int P2P_SUBCATEGORY_MFP = 5;
        public static final int P2P_SUBCATEGORY_PRINTER = 1;
        private int categoryId = 0;
        private int subCategoryId = 0;

        public static boolean isPrinter(String str) {
            PrimaryDeviceType parsePrimaryDeviceType = parsePrimaryDeviceType(str);
            if (parsePrimaryDeviceType == null || 3 != parsePrimaryDeviceType.categoryId) {
                return false;
            }
            int i = parsePrimaryDeviceType.subCategoryId;
            if (1 == i || 5 == i) {
                return true;
            }
            return false;
        }

        private static PrimaryDeviceType parsePrimaryDeviceType(String str) {
            PrimaryDeviceType primaryDeviceType = new PrimaryDeviceType();
            primaryDeviceType.categoryId = 0;
            primaryDeviceType.subCategoryId = 0;
            if (str == null || str.isEmpty()) {
                return primaryDeviceType;
            }
            str.toUpperCase(Locale.ENGLISH);
            String replaceAll = str.replaceAll("[^(0-9)^(A-Z)]", "");
            int indexOf = replaceAll.indexOf(DEMIRITA_WIFI_OUI);
            if (indexOf < 0) {
                return primaryDeviceType;
            }
            String substring = replaceAll.substring(0, indexOf);
            String substring2 = replaceAll.substring(indexOf + 8);
            try {
                primaryDeviceType.categoryId = Integer.parseInt(substring, 16);
                primaryDeviceType.subCategoryId = Integer.parseInt(substring2, 16);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
            return primaryDeviceType;
        }
    }
}
