package com.qianmi.hardwarekit.bluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.text.TextUtils;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by xiayinglin on 20/03/2018.
 */

public class BluetoothThreadPool {

    private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();

    private static BluetoothThreadPool pool = new BluetoothThreadPool();

    private Map<String, BluetoothSocket> mSockets = Collections.synchronizedMap(new HashMap<String, BluetoothSocket>());


    private static final UUID SPP_UUID =
//            UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66"); android蓝牙设备
            UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");    //非蓝牙设备

    private BluetoothThreadPool() {

       /* mExecutor.submit(new Runnable() {
            @Override
            public void run() {

                while (true) {

                    List<String> removes = new ArrayList<>();
                    for (Map.Entry<String, BluetoothSocket> entry : mSockets.entrySet()) {
                        BluetoothSocket bsc = entry.getValue();
                        if (null != bsc) {
                            if (!bsc.isConnected()) {
                                removes.add(entry.getKey());
                            }
                        }
                    }

                    for (String address : removes) {
                        disconnect(address);
                    }

                    removes.clear();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });*/


        mExecutor.submit(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {

                        for (Map.Entry<String, BluetoothSocket> entry : mSockets.entrySet()) {
                            BluetoothSocket bsc = entry.getValue();
                            if (null != bsc) {

                                InputStream in = bsc.getInputStream();
                                byte b[] = new byte[in.available()];        // 数组大小由文件决定
                                int r = in.read(b);
                                if (0 <= r) {
                                    String result = new String(b);
                                    Log.d(getClass().getSimpleName(), entry.getKey() + ':' + result);
                                }
                            }
                        }
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        Log.e(getClass().getSimpleName(), e.toString());
                    }
                }
            }
        });

    }


    public static BluetoothThreadPool instance() {
        return pool;
    }


    /**
     * 蓝牙连接
     *
     * @param address
     */
    public BluetoothDevice connect(final String address) {
        Log.d(getClass().getSimpleName(), "--- connect ---");
        final BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);

        new Thread(new Runnable() {
            @Override
            public void run() {
                if (null != device) {
                    try {
                        BluetoothSocket socket = device.createRfcommSocketToServiceRecord(SPP_UUID);
                        if (add(address, socket)) {
                            socket.connect();
                        }
                    } catch (IOException e) {
                        Log.e(getClass().getSimpleName(), e.toString());
//                        disconnect(address);
                    }
                }
            }
        }).start();

        return device;
    }


    public void write(final String address, final String text, final String charSet) {
        final BluetoothSocket bsc = get(address);

//        new Thread(new Runnable() {
//            @Override
//            public void run() {
        OutputStream out = null;
        if (null != bsc) {
            try {
                out = bsc.getOutputStream();
                out.write(text.getBytes(TextUtils.isEmpty(charSet) ? "GBK" : charSet));
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != out) {
                        out.flush();
//                        out.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
//            }
//        }).start();


    }


    /**
     * 蓝牙断开
     *
     * @param address
     */
    public void disconnect(final String address) {
        Log.d(getClass().getSimpleName(), "--- disconnect ---");

        BluetoothSocket bsc = get(address);
        if (null != bsc) {
            try {
                OutputStream out = bsc.getOutputStream();
                if (null != out) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    bsc.close();
                    remove(address);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private BluetoothSocket get(String address) {
        return mSockets.get(address);
    }

    private boolean add(String address, BluetoothSocket socket) {
        if (!mSockets.containsKey(address)) {
            mSockets.put(address, socket);
            return true;
        }
        return false;
    }

    private void remove(String address) {
        if (mSockets.containsKey(address)) {
            mSockets.remove(address);
        }
    }


}
