package com.xixun.communicate;

/**
 * Created by Administrator on 2018/01/19.
 */

import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;

import com.xixun.display.MyLog;

import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.sql.SQLOutput;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class NetDevicesManage {

    public LinkedList hostsTable=null;

    private boolean bNetChange=false;
    private WifiManager wifiManager =null;

    private LedCardCommunication ledCardCommunication=null;

    public NetDevicesManage(LedCardCommunication ledCardCommunication) {

        this.ledCardCommunication=ledCardCommunication;

        if (true)
            new Thread() {
            public void run() {
                Process();
            }
        }.start();
    }

    void  Process() {
        if (ledCardCommunication==null) return;
        if (ledCardCommunication.clientsManage==null) return;
        if (ledCardCommunication.clientsManage.ms==null) return;

        hostsTable=new LinkedList();
        //获取wifi服务
        wifiManager = (WifiManager) ledCardCommunication.clientsManage.ms.getApplicationContext().getSystemService(Context.WIFI_SERVICE);


        while (NeedExit() == false) {
            Wifi_SetOn();
            getLocalIpAddress();
            try {
                Thread.sleep(8000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        hostsTable.clear();
    }

    public String getLocalIpAddress()
    {
        try
        {   int iCounter=0;
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
            {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
                {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress())
                        if (inetAddress.isSiteLocalAddress())
                        {
                            String strIpAddress=inetAddress.getHostAddress().toString();
                            //MyLog.i("=====================IP1: "+strIpAddress);

                            if (strIpAddress!=null) {
                                iCounter++;
                                if (JundgeHostExist(strIpAddress) == false) {
                                    hostsTable.add(strIpAddress);
                                    MyLog.i("Add new IP Adddress: " + strIpAddress);
                                    bNetChange = true;
                                }
                            }
                            //MyLog.i("=====================");
                            //MyLog.i("IP1: "+inetAddress.getHostAddress().toString());
                        }
                }
            }

            if (false)
                if (iCounter!=hostsTable.size())
            {   iCounter=hostsTable.size();
                bNetChange=true;
                MyLog.i("Clear All IP Adddress: " + hostsTable.size());
            }
        }
        catch (SocketException e)   {
            if (NeedExit() == false)
                MyLog.i(Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                    +   "Function: " +Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                    +   "Line" +Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                    +   "    Error:" + e.getMessage() + "\r\n\r\n"
            );
        }
        return null;
    }

    public String GetLocalIP()
    {   if (hostsTable.size()==0) return null;
        return (String) hostsTable.get(0);
    }


    boolean JundgeHostExist(String hostIP)
    {   for (int iOffset=0;iOffset<hostsTable.size();iOffset++) {
            //MyLog.i("--------IP"+iOffset+" : "+(String)hostsTable.get(iOffset));
            if (hostIP.equals((String)hostsTable.get(iOffset))) return true;
        }
        return false;
    }

    public static List<String> GetBoardCastIp() {
        List<String> ips = new ArrayList<>();
        //MyLog.i( "=================10");
        try {
            Enumeration<NetworkInterface> eni = NetworkInterface.getNetworkInterfaces();
            while (eni.hasMoreElements()) {
                NetworkInterface networkCard = eni.nextElement();
                if (!networkCard.isUp()) { // 判断网卡是否在使用
                    continue;
                }
                //MyLog.i( "=================11");

                String DisplayName = networkCard.getDisplayName();

                List<InterfaceAddress> addressList = networkCard.getInterfaceAddresses();
                Iterator<InterfaceAddress> addressIterator = addressList.iterator();

                //MyLog.i( "=================12");
                while (addressIterator.hasNext()) {
                    InterfaceAddress interfaceAddress = addressIterator.next();
                    InetAddress address = interfaceAddress.getAddress();
                    if (address.isLoopbackAddress()) {
                        continue;
                    }
                    String hostAddress = address.getHostAddress();
                    if (!hostAddress.contains(":")) {
                        //MyLog.i( "=================13");
                        String maskAddress = calcMaskByPrefixLength(interfaceAddress.getNetworkPrefixLength());
                        String gateway = calcSubnetAddress(hostAddress, maskAddress);

                        String broadcastAddress = null;
                        InetAddress broadcast = interfaceAddress.getBroadcast();
                        if (broadcast != null)
                            broadcastAddress = broadcast.getHostAddress();

//                            MyLog.i("----- DisplayName    =   " + DisplayName);
//                            MyLog.i("----- address        =   " + hostAddress);
//                            MyLog.i("----- mask           =   " + maskAddress);
//                            MyLog.i("----- gateway        =   " + gateway);
//                            MyLog.i("----- broadcast      =   " + broadcastAddress + "\n");
                        if (null != broadcastAddress) {
                            ips.add(broadcastAddress);
                        }
                    }
                }
            }
            return ips;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void printIpAddress() {
        try {
            Enumeration<NetworkInterface> eni = NetworkInterface.getNetworkInterfaces();
            while (eni.hasMoreElements()) {

                NetworkInterface networkCard = eni.nextElement();
                if (!networkCard.isUp()) { // 判断网卡是否在使用
                    continue;
                }

                String DisplayName = networkCard.getDisplayName();

                List<InterfaceAddress> addressList = networkCard.getInterfaceAddresses();
                Iterator<InterfaceAddress> addressIterator = addressList.iterator();
                while (addressIterator.hasNext()) {
                    InterfaceAddress interfaceAddress = addressIterator.next();
                    InetAddress address = interfaceAddress.getAddress();
                    if (!address.isLoopbackAddress()) {
                        String hostAddress = address.getHostAddress();

                        if (hostAddress.indexOf(":") > 0) {
                        } else {
                            String maskAddress = calcMaskByPrefixLength(interfaceAddress.getNetworkPrefixLength());
                            String gateway = calcSubnetAddress(hostAddress, maskAddress);

                            String broadcastAddress = null;
                            InetAddress broadcast = interfaceAddress.getBroadcast();
                            if (broadcast != null)
                                broadcastAddress = broadcast.getHostAddress();

                            MyLog.i("----- DisplayName    =   " + DisplayName);
                            MyLog.i("----- address        =   " + hostAddress);
                            MyLog.i("----- mask           =   " + maskAddress);
                            MyLog.i("----- gateway        =   " + gateway);
                            MyLog.i("----- broadcast      =   " + broadcastAddress + "\n");
                            MyLog.i("----- NetworkInterface  Separator ----\n\n");
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String calcMaskByPrefixLength(int length) {

        int mask = 0xffffffff << (32 - length);
        int partsNum = 4;
        int bitsOfPart = 8;
        int maskParts[] = new int[partsNum];
        int selector = 0x000000ff;

        for (int i = 0; i < maskParts.length; i++) {
            int pos = maskParts.length - 1 - i;
            maskParts[pos] = (mask >> (i * bitsOfPart)) & selector;
        }

        String result = "";
        result = result + maskParts[0];
        for (int i = 1; i < maskParts.length; i++) {
            result = result + "." + maskParts[i];
        }
        return result;
    }

    public static String calcSubnetAddress(String ip, String mask) {
        String result = "";
        try {
            // calc sub-net IP
            InetAddress ipAddress = InetAddress.getByName(ip);
            InetAddress maskAddress = InetAddress.getByName(mask);

            byte[] ipRaw = ipAddress.getAddress();
            byte[] maskRaw = maskAddress.getAddress();

            int unsignedByteFilter = 0x000000ff;
            int[] resultRaw = new int[ipRaw.length];
            for (int i = 0; i < resultRaw.length; i++) {
                resultRaw[i] = (ipRaw[i] & maskRaw[i] & unsignedByteFilter);
            }

            // make result string
            result = result + resultRaw[0];
            for (int i = 1; i < resultRaw.length; i++) {
                result = result + "." + resultRaw[i];
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        return result;
    }

    public static String GetBoardCastIp(String strIP,String strMask)
    {
        if (strIP==null) return Define.AllNetBroadcaseIP;
        if (strIP.length()<"1.1.1.1".length())  return Define.AllNetBroadcaseIP;
        if (strMask==null) return Define.AllNetBroadcaseIP;
        if (strMask.length()<"1.1.1.1".length())  return Define.AllNetBroadcaseIP;

        //MyLog.i("strIP: "+strIP);
        //MyLog.i("strMask: "+strMask);

        int iCounter=0;
        int IpSeg[]=new int[4];
        int MaskSeg[]=new int[4];
        int BocastIPSeg[]=new int[4];

        String[] strIPs = strIP.split("\\.");
        String[] strMasks = strMask.split("\\.");

        if (strIPs.length!=4) return Define.AllNetBroadcaseIP;
        if (strMasks.length!=4) return Define.AllNetBroadcaseIP;

        // 把网段换算成整数值。
        {   iCounter=0;
            for (String string : strIPs)
                IpSeg[iCounter++]=Integer.parseInt(string);

            iCounter=0;
            for (String string : strMasks)
                MaskSeg[iCounter++]=Integer.parseInt(string);
        }
        // 按位算出精确的通播地址。
        {
            for (iCounter=0;iCounter<4;iCounter++)
            {   BocastIPSeg[iCounter]=0;

                for (int i=0;i<8;i++)
                {
                    if ((MaskSeg[iCounter]&(1<<i))==0) // 掩码为0，则通播地址需为1.
                    {   BocastIPSeg[iCounter]|=(1<<i);
                    }
                    else  // 掩码为1，则通播地址为IP地址对应的位.
                    {   if ((IpSeg[iCounter]&(1<<i))!=0)
                        BocastIPSeg[iCounter]|=(1<<i);
                    }
                }
            }
        }

        return ""+BocastIPSeg[0]+"."+BocastIPSeg[1]+"."+BocastIPSeg[2]+"."+BocastIPSeg[3];
    }


    void Wifi_SetOn()
    {   //判断wifi是否开启
        //if (!wifiManager.isWifiEnabled())
        {
            wifiManager.setWifiEnabled(true);
        }
        /* */
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int ipAddress = wifiInfo.getIpAddress();
        String ip = intToIp(ipAddress);
        MyLog.i("=====================Wifi_SetOn:"+ip);
        //wifiManager.isScanAlwaysAvailable()
    }


    private String intToIp(int i) {
        return (i & 0xFF ) + "." +
                ((i >> 8 ) & 0xFF) + "." +
                ((i >> 16 ) & 0xFF) + "." +
                ( i >> 24 & 0xFF) ;
    }

    //根据Wifi信息获取本地Mac
    public String getLocalMacAddressFromWifiInfo(){
        if (wifiManager==null) return null;
        WifiInfo info = wifiManager.getConnectionInfo();
        if (info==null) return null;
        return info.getMacAddress(); // 88:e3:ab:eb:ab:a2
    }


    Boolean bNeedExit=false;
    boolean NeedExit() { return bNeedExit; }

    public void Exit() {
        if (NeedExit()) return;
        bNeedExit=true;
        if (hostsTable!=null) hostsTable.clear();
        MyLog.i(" "+ Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                +   "Function: " +Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                +   "Line" +Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
        );
    }
}
