package com.cpm.lorealbaautomation.autoconnectblutooth;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.util.Log;

public class BluetoothBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "BluetoothBroadcastReceiver";

    private Callback mCallback;

    private BluetoothBroadcastReceiver (Callback callback) {
        mCallback = callback;
    }

    /**
     * Convenience method to register a new instance of this receiver with the
     * necessary IntentFilter, which will notify the callback upon a successful
     * connection or error case.
     * @param callback the callback that should be notified on success or failure
     *                 of Bluetooth being enabled
     * @param c the context from which to register the receiver
     */

    @SuppressLint("UnspecifiedRegisterReceiverFlag")
    public static void register (Callback callback, Context c) {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2){
        c.registerReceiver(new BluetoothBroadcastReceiver(callback), getFilter());
        }else {
            c.registerReceiver(new BluetoothBroadcastReceiver(callback), getFilter(), Context.RECEIVER_NOT_EXPORTED);
        }
    }

    private static IntentFilter getFilter () {
        return new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
    }

    @SuppressLint("LongLogTag")
    @Override
    public void onReceive (Context context, Intent intent) {
        if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
            Log.v(TAG, "Received irrelevant broadcast. Disregarding.");
            return;
        }

        //This is a State Change event, get the state extra, falling back to ERROR
        //if it isn't there (which shouldn't happen)
        int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);

        switch (state) {
            case BluetoothAdapter.STATE_CONNECTED:
                safeUnregisterReceiver(context, this);
                fireOnBluetoothConnected();
                break;
            case BluetoothAdapter.ERROR:
                safeUnregisterReceiver(context, this);
                fireOnBluetoothError();
                break;
        }
    }

    /**
     * Convenience method to do a checked unregistration of a broadcast receiver. Occasionally
     * you can get into a state where the receiver was already unregistered, throwing an
     * IllegalArgumentException. This method just swallows that exception and logs the error.
     * @param c the context from which to unregister the receiver
     * @param receiver the receiver that should be unregistered if it is not already unregistered
     */
    private static void safeUnregisterReceiver (Context c, BroadcastReceiver receiver) {
        try {
            c.unregisterReceiver(receiver);
        } catch (IllegalArgumentException ex) {
            Log.w(TAG, "Tried to unregister BluetoothBroadcastReceiver that was not registered.");
        }
    }

    private void fireOnBluetoothConnected () {
        if (mCallback != null) {
            mCallback.onBluetoothConnected();
        }
    }

    private void fireOnBluetoothError () {
        if (mCallback != null) {
            mCallback.onBluetoothError();
        }
    }

    public static interface Callback {
        public void onBluetoothConnected();
        public void onBluetoothError();
    }
}