// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.android.impl.google.rpc.protocols.bt;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;

import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;

import org.joda.time.Duration;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import io.v.v23.verror.VException;

/**
 * Handles bluetooth connection establishment on Android.
 * <p>
 * Used as a helper class for native code which sets up and registers the bluetooth protocol with
 * the vanadium RPC service.
 */
class Bluetooth {
    private static final List<Integer> BLUETOOTH_PORTS = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9,
            10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31);

    static Listener listen(String btAddr) throws VException {
        String macAddr = getMACAddress(btAddr);
        int port = getPortNumber(btAddr);
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        if (!macAddr.equals(adapter.getAddress())) {
            throw new VException("Illegal MAC address to listen on: no local device found with "
                    + "MAC address: " + macAddr + " (local address is: " + adapter.getAddress()
                    + " )");
        }
        List<Integer> ports = null;
        if (port == 0) {  // listen on the first available port.
            ports = new ArrayList(BLUETOOTH_PORTS);
            Collections.shuffle(ports);
        } else {  // listen on a specific port only
            ports = ImmutableList.of(port);
        }
        VException lastError = null;
        for (int portNum : ports) {
            try {
                BluetoothServerSocket socket = listenOnPort(portNum);
                return new Listener(socket, String.format("%s/%d", macAddr, portNum));
            } catch (VException e) {
                // OK, try the next one
                lastError = e;
            }
        }
        throw lastError;
    }

    static Connection dial(String btAddr, Duration timeout) throws VException {
        String macAddr = getMACAddress(btAddr);
        int port = getPortNumber(btAddr);
        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(macAddr);
        try {
            // Create a socket to the remote device.
            // NOTE(spetrovic): Android's public methods currently only allow connection to a
            // UUID, which goes through SDP.  Since we already have a remote port number, we
            // connect to it directly.
            Method m = device.getClass().getMethod("createInsecureRfcommSocket",
                    new Class[]{int.class});
            final BluetoothSocket socket = (BluetoothSocket) m.invoke(device, port);
            // Connect.
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        System.err.println("Couldn't close BluetoothSocket.");
                    }
                }
            }, timeout.getMillis());
            try {
                socket.connect();
            } catch (IOException e) {
                throw new VException("Couldn't connect: " + e.getMessage());
            } finally {
                timer.cancel();
            }
            // There is no way currently to retrieve the local port number for the connection,
            // but that's probably OK.
            String localAddr = String.format("%s/%d",
                    BluetoothAdapter.getDefaultAdapter().getAddress(), 0);
            String remoteAddr = String.format("%s/%d", macAddr, port);
            return new Connection(socket, localAddr, remoteAddr);
        } catch (Exception e) {
            throw new VException("Couldn't invoke createInsecureRfcommSocket: "
                    + e.getMessage());
        }
    }

    private static BluetoothServerSocket listenOnPort(int port) throws VException {
        // Use reflection to reach the hidden "listenUsingInsecureRfcommOn(port)" method.
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        try {
            Method m = adapter.getClass().
                    getMethod("listenUsingInsecureRfcommOn", new Class[]{int.class});
            return (BluetoothServerSocket) m.invoke(adapter, port);
        } catch (Exception e) {
            throw new VException("Error invoking listenUsingInsecureRfcommOn: "
                    + e.getMessage());
        }
    }

    private static String getMACAddress(String btAddr) throws VException {
        List<String> parts = Splitter.on("/").omitEmptyStrings().splitToList(btAddr);
        switch (parts.size()) {
            case 0:
                throw new VException(String.format(
                        "Couldn't split bluetooth address \"%s\" using \"/\" separator: " +
                                "got zero parts!", btAddr));
            case 1:
                return BluetoothAdapter.getDefaultAdapter().getAddress();
            case 2:
                String address = parts.get(0).toUpperCase();
                if (!BluetoothAdapter.checkBluetoothAddress(address)) {
                    throw new VException("Invalid bluetooth address: " + btAddr);
                }
                return address;
            default:
                throw new VException(String.format(
                        "Couldn't parse bluetooth address \"%s\": too many \"/\".", btAddr));
        }
    }

    private static int getPortNumber(String btAddr) throws VException {
        List<String> parts = Splitter.on("/").splitToList(btAddr);
        switch (parts.size()) {
            case 0:
                throw new VException(String.format(
                        "Couldn't split bluetooth address \"%s\" using \"/\" separator: " +
                                "got zero parts!", btAddr));
            case 1:
            case 2:
                try {
                    int port = Integer.parseInt((parts.get(parts.size() - 1)));
                    if (port < 0 || port > 32) {
                        throw new VException(String.format("Illegal port number %q in bluetooth " +
                                "address \"%s\".", port, btAddr));
                    }
                    return port;
                } catch (NumberFormatException e) {
                    throw new VException(String.format(
                            "Couldn't parse port number in bluetooth address \"%s\": %s",
                            btAddr, e.getMessage()));
                }
            default:
                throw new VException(String.format(
                        "Couldn't parse bluetooth address \"%s\": too many \"/\".", btAddr));
        }
    }

    static class Listener {
        private final BluetoothServerSocket serverSocket;
        private final String localAddress;

        Listener(BluetoothServerSocket serverSocket, String address) {
            this.serverSocket = serverSocket;
            this.localAddress = address;
        }

        Connection accept() throws IOException {
            BluetoothSocket socket = serverSocket.accept();
            // There is no way currently to retrieve the remote end's channel number, but that's
            // probably OK.
            String remoteAddress = String.format("%s/%d", socket.getRemoteDevice().getAddress(), 0);
            return new Connection(socket, localAddress, remoteAddress);
        }

        void close() throws IOException {
            serverSocket.close();
        }

        String address() {
            return localAddress;
        }
    }

    static class Connection {
        private final BluetoothSocket socket;
        private final String localAddress;
        private final String remoteAddress;

        Connection(BluetoothSocket socket, String localAddress, String remoteAddress) {
            this.socket = socket;
            this.localAddress = localAddress;
            this.remoteAddress = remoteAddress;
        }

        byte[] read(int n) throws IOException {
            byte[] buf = new byte[n];
            int num = socket.getInputStream().read(buf);
            return num == buf.length ? buf : Arrays.copyOf(buf, num);
        }

        synchronized void write(byte[] data) throws IOException {
            socket.getOutputStream().write(data);
        }

        void close() throws IOException {
            socket.close();
        }

        String localAddress() {
            return this.localAddress;
        }

        String remoteAddress() {
            return this.remoteAddress;
        }
    }

    private Bluetooth() {}
}
