/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.bluetooth.cts;

import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.ParcelUuid;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;
import android.util.SparseArray;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Test cases for Bluetooth LE scans.
 * <p>
 * To run the test, the device must be placed in an environment that has at least 3 beacons, all
 * placed less than 5 meters away from the DUT.
 * <p>
 * Run 'run cts --class android.bluetooth.cts.BluetoothLeScanTest' in cts-tradefed to run the test
 * cases.
 */
public class BluetoothLeScanTest extends AndroidTestCase {

    private static final String TAG = "BluetoothLeScanTest";

    private static final int SCAN_DURATION_MILLIS = 10000;
    private static final int BATCH_SCAN_REPORT_DELAY_MILLIS = 20000;
    private static final int SCAN_STOP_TIMEOUT = 2000;
    private static final int ADAPTER_ENABLE_TIMEOUT = 3000;
    private CountDownLatch mFlushBatchScanLatch;

    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothLeScanner mScanner;
    // Whether location is on before running the tests.
    private boolean mLocationOn;

    @Override
    public void setUp() {
        if (!isBleSupported()) {
            return;
        }
        BluetoothManager manager = (BluetoothManager) mContext.getSystemService(
                Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = manager.getAdapter();
        if (!mBluetoothAdapter.isEnabled()) {
            // Note it's not reliable to listen for Adapter.ACTION_STATE_CHANGED broadcast and check
            // bluetooth state.
            mBluetoothAdapter.enable();
            sleep(ADAPTER_ENABLE_TIMEOUT);
        }
        mScanner = mBluetoothAdapter.getBluetoothLeScanner();
        mLocationOn = TestUtils.isLocationOn(getContext());
        if (!mLocationOn) {
            TestUtils.enableLocation(getContext());
        }
        InstrumentationRegistry.getInstrumentation().getUiAutomation().grantRuntimePermission(
                "android.bluetooth.cts", android.Manifest.permission.ACCESS_COARSE_LOCATION);
    }

    @Override
    public void tearDown() {
        if (!isBleSupported()) {
          // mBluetoothAdapter == null.
          return;
        }

        if (!mLocationOn) {
            TestUtils.disableLocation(getContext());
        }
        mBluetoothAdapter.disable();
        sleep(ADAPTER_ENABLE_TIMEOUT);
    }

    /**
     * Basic test case for BLE scans. Checks BLE scan timestamp is within correct range.
     */
    @MediumTest
    public void testBasicBleScan() {
        if (!isBleSupported()) {
            return;
        }
        long scanStartMillis = SystemClock.elapsedRealtime();
        Collection<ScanResult> scanResults = scan();
        long scanEndMillis = SystemClock.elapsedRealtime();
        Log.d(TAG, "scan result size:" + scanResults.size());
        assertTrue("Scan results shouldn't be empty", !scanResults.isEmpty());
        verifyTimestamp(scanResults, scanStartMillis, scanEndMillis);
    }

    /**
     * Test of scan filters. Ensures only beacons matching certain type of scan filters were
     * reported.
     */
    @MediumTest
    public void testScanFilter() {
        if (!isBleSupported()) {
            return;
        }

        List<ScanFilter> filters = new ArrayList<ScanFilter>();
        ScanFilter filter = createScanFilter();
        if (filter == null) {
            Log.d(TAG, "no appropriate filter can be set");
            return;
        }
        filters.add(filter);

        BleScanCallback filterLeScanCallback = new BleScanCallback();
        ScanSettings settings = new ScanSettings.Builder().setScanMode(
                ScanSettings.SCAN_MODE_LOW_LATENCY).build();
        mScanner.startScan(filters, settings, filterLeScanCallback);
        sleep(SCAN_DURATION_MILLIS);
        mScanner.stopScan(filterLeScanCallback);
        sleep(SCAN_STOP_TIMEOUT);
        Collection<ScanResult> scanResults = filterLeScanCallback.getScanResults();
        for (ScanResult result : scanResults) {
            assertTrue(filter.matches(result));
        }
    }

    // Create a scan filter based on the nearby beacon with highest signal strength.
    private ScanFilter createScanFilter() {
        // Get a list of nearby beacons.
        List<ScanResult> scanResults = new ArrayList<ScanResult>(scan());
        assertTrue("Scan results shouldn't be empty", !scanResults.isEmpty());
        // Find the beacon with strongest signal strength, which is the target device for filter
        // scan.
        Collections.sort(scanResults, new RssiComparator());
        ScanResult result = scanResults.get(0);
        ScanRecord record = result.getScanRecord();
        if (record == null) {
            return null;
        }
        Map<ParcelUuid, byte[]> serviceData = record.getServiceData();
        if (serviceData != null && !serviceData.isEmpty()) {
            ParcelUuid uuid = serviceData.keySet().iterator().next();
            return new ScanFilter.Builder().setServiceData(uuid, new byte[]{0},
                    new byte[]{0}).build();
        }
        SparseArray<byte[]> manufacturerSpecificData = record.getManufacturerSpecificData();
        if (manufacturerSpecificData != null && manufacturerSpecificData.size() > 0) {
            return new ScanFilter.Builder().setManufacturerData(manufacturerSpecificData.keyAt(0),
                    new byte[]{0}, new byte[]{0}).build();
        }
        List<ParcelUuid> serviceUuids = record.getServiceUuids();
        if (serviceUuids != null && !serviceUuids.isEmpty()) {
            return new ScanFilter.Builder().setServiceUuid(serviceUuids.get(0)).build();
        }
        return null;
    }

//    /**
//     * Test of opportunistic BLE scans.
//     * Temporarily disable this test because it is interfered by the GmsCore;
//     * it fails when it obtains results from GmsCore explicit scan.
//     * TODO(b/70865144): re-enable this test.
//     */
//    @MediumTest
//    public void testOpportunisticScan() {
//        if (!isBleSupported()) {
//            return;
//        }
//        ScanSettings opportunisticScanSettings = new ScanSettings.Builder()
//                .setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC)
//                .build();
//        BleScanCallback emptyScanCallback = new BleScanCallback();
//        assertTrue("opportunistic scan shouldn't have scan results",
//                emptyScanCallback.getScanResults().isEmpty());
//
//        // No scans are really started with opportunistic scans only.
//        mScanner.startScan(Collections.<ScanFilter>emptyList(), opportunisticScanSettings,
//                emptyScanCallback);
//        sleep(SCAN_DURATION_MILLIS);
//        Log.d(TAG, "result: " + emptyScanCallback.getScanResults());
//        assertTrue("opportunistic scan shouldn't have scan results",
//                emptyScanCallback.getScanResults().isEmpty());
//
//        BleScanCallback regularScanCallback = new BleScanCallback();
//        ScanSettings regularScanSettings = new ScanSettings.Builder()
//                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
//        List<ScanFilter> filters = new ArrayList<>();
//        ScanFilter filter = createScanFilter();
//        if (filter != null) {
//            filters.add(filter);
//        } else {
//            Log.d(TAG, "no appropriate filter can be set");
//        }
//        mScanner.startScan(filters, regularScanSettings, regularScanCallback);
//        sleep(SCAN_DURATION_MILLIS);
//        // With normal BLE scan client, opportunistic scan client will get scan results.
//        assertTrue("opportunistic scan results shouldn't be empty",
//                !emptyScanCallback.getScanResults().isEmpty());
//
//        // No more scan results for opportunistic scan clients once the normal BLE scan clients
//        // stops.
//        mScanner.stopScan(regularScanCallback);
//        // In case we got scan results before scan was completely stopped.
//        sleep(SCAN_STOP_TIMEOUT);
//        emptyScanCallback.clear();
//        sleep(SCAN_DURATION_MILLIS);
//        assertTrue("opportunistic scan shouldn't have scan results",
//                emptyScanCallback.getScanResults().isEmpty());
//    }

    /**
     * Test case for BLE Batch scan.
     */
    @MediumTest
    public void testBatchScan() {
        if (!isBleSupported() || !isBleBatchScanSupported()) {
            Log.d(TAG, "BLE or BLE batching not suppported");
            return;
        }
        ScanSettings batchScanSettings = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .setReportDelay(BATCH_SCAN_REPORT_DELAY_MILLIS).build();
        BleScanCallback batchScanCallback = new BleScanCallback();
        mScanner.startScan(Collections.<ScanFilter>emptyList(), batchScanSettings,
                batchScanCallback);
        sleep(SCAN_DURATION_MILLIS);
        mScanner.flushPendingScanResults(batchScanCallback);
        mFlushBatchScanLatch = new CountDownLatch(1);
        List<ScanResult> results = batchScanCallback.getBatchScanResults();
        try {
            mFlushBatchScanLatch.await(5, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            // Nothing to do.
            Log.e(TAG, "interrupted!");
        }
        assertTrue(!results.isEmpty());
        long scanEndMillis = SystemClock.elapsedRealtime();
        mScanner.stopScan(batchScanCallback);
        verifyTimestamp(results, 0, scanEndMillis);
    }

    /**
     * Test case for starting a scan with a PendingIntent.
     */
    @MediumTest
    public void testStartScanPendingIntent_nullnull() throws Exception {
        if (!isBleSupported() || !isBleBatchScanSupported()) {
            Log.d(TAG, "BLE or BLE batching not suppported");
            return;
        }
        Intent broadcastIntent = new Intent();
        broadcastIntent.setClass(mContext, BluetoothScanReceiver.class);
        PendingIntent pi = PendingIntent.getBroadcast(mContext, 1, broadcastIntent, 0);
        CountDownLatch latch = BluetoothScanReceiver.createCountDownLatch();
        mScanner.startScan(null, null, pi);
        boolean gotResults = latch.await(20, TimeUnit.SECONDS);
        mScanner.stopScan(pi);
        assertTrue("Scan results not received", gotResults);
    }

    /**
     * Test case for starting a scan with a PendingIntent.
     */
    @MediumTest
    public void testStartScanPendingIntent() throws Exception {
        if (!isBleSupported() || !isBleBatchScanSupported()) {
            Log.d(TAG, "BLE or BLE batching not suppported");
            return;
        }
        ScanSettings batchScanSettings = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .setReportDelay(0).build();
        ScanFilter filter = createScanFilter();
        ArrayList<ScanFilter> filters = null;
        if (filter != null) {
            filters = new ArrayList<>();
            filters.add(filter);
        } else {
            Log.d(TAG, "Could not add a filter");
        }
        Intent broadcastIntent = new Intent();
        broadcastIntent.setClass(mContext, BluetoothScanReceiver.class);
        PendingIntent pi = PendingIntent.getBroadcast(mContext, 1, broadcastIntent, 0);
        CountDownLatch latch = BluetoothScanReceiver.createCountDownLatch();
        mScanner.startScan(filters, batchScanSettings, pi);
        boolean gotResults = latch.await(20, TimeUnit.SECONDS);
        mScanner.stopScan(pi);
        assertTrue("Scan results not received", gotResults);
    }

    // Verify timestamp of all scan results are within [scanStartMillis, scanEndMillis].
    private void verifyTimestamp(Collection<ScanResult> results, long scanStartMillis,
            long scanEndMillis) {
        for (ScanResult result : results) {
            long timestampMillis = TimeUnit.NANOSECONDS.toMillis(result.getTimestampNanos());
            assertTrue("Invalid timestamp: " + timestampMillis + " should be >= " + scanStartMillis,
                    timestampMillis >= scanStartMillis);
            assertTrue("Invalid timestamp: " + timestampMillis + " should be <= " + scanEndMillis,
                    timestampMillis <= scanEndMillis);
        }
    }

    // Helper class for BLE scan callback.
    private class BleScanCallback extends ScanCallback {
        private Set<ScanResult> mResults = new HashSet<ScanResult>();
        private List<ScanResult> mBatchScanResults = new ArrayList<ScanResult>();

        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES) {
                mResults.add(result);
            }
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            // In case onBatchScanResults are called due to buffer full, we want to collect all
            // scan results.
            mBatchScanResults.addAll(results);
            if (mFlushBatchScanLatch != null) {
                mFlushBatchScanLatch.countDown();
            }
        }

        // Clear regular and batch scan results.
        synchronized public void clear() {
            mResults.clear();
            mBatchScanResults.clear();
        }

        // Return regular BLE scan results accumulated so far.
        synchronized Set<ScanResult> getScanResults() {
            return Collections.unmodifiableSet(mResults);
        }

        // Return batch scan results.
        synchronized List<ScanResult> getBatchScanResults() {
            return Collections.unmodifiableList(mBatchScanResults);
        }
    }

    private class RssiComparator implements Comparator<ScanResult> {

        @Override
        public int compare(ScanResult lhs, ScanResult rhs) {
            return rhs.getRssi() - lhs.getRssi();
        }

    }

    // Perform a BLE scan to get results of nearby BLE devices.
    private Set<ScanResult> scan() {
        BleScanCallback regularLeScanCallback = new BleScanCallback();
        mScanner.startScan(regularLeScanCallback);
        sleep(SCAN_DURATION_MILLIS);
        mScanner.stopScan(regularLeScanCallback);
        sleep(SCAN_STOP_TIMEOUT);
        return regularLeScanCallback.getScanResults();
    }

    // Put the current thread to sleep.
    private void sleep(int sleepMillis) {
        try {
            Thread.sleep(sleepMillis);
        } catch (InterruptedException e) {
            Log.e(TAG, "interrupted", e);
        }
    }

    // Check if Bluetooth LE feature is supported on DUT.
    private boolean isBleSupported() {
        return getContext().getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
    }

    // Returns whether offloaded scan batching is supported.
    private boolean isBleBatchScanSupported() {
        return mBluetoothAdapter.isOffloadedScanBatchingSupported();
    }

}
