/*
 * Copyright (C) 2017 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 com.android.pmc;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * Bluetooth LE Receiver functions for power testing.
 */
public class BleScanReceiver extends BroadcastReceiver {
    public static final String TAG = "BLEPOWER";
    public static final String BLE_SCAN_INTENT = "com.android.pmc.BLESCAN";
    public static final int START_SCAN = 1;
    public static final int STOP_SCAN = 2;
    public static final int INIT_ALARM_NO = 1;
    private final Context mContext;
    private final AlarmManager mAlarmManager;
    private final BleScanListener mAlarmScanListener;
    private BluetoothLeScanner mBleScanner;
    private ScanSettings mScanSettings;
    private List<ScanFilter> mScanFilterList;

    private ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            Log.e(TAG, "Bluetooth scan result: " + result.toString());
        }

        @Override
        public void onScanFailed(int errorCode) {
            Log.e(TAG, "Scan Failed: " + errorCode);
        }
    };

    /**
     * Class to provide callback for AlarmManager to start BLE scan alarms
     */
    public class BleScanListener extends BroadcastReceiver {

        public static final String BLESCAN =
                       "com.android.pmc.BLESCAN.ALARM";

        private int mScanTime;
        private int mNoScanTime;
        private int mNumAlarms;

        /**
         * Constructor
         *
         */
        public BleScanListener() {
            BluetoothAdapter bleAdaptor = BluetoothAdapter.getDefaultAdapter();

            if (bleAdaptor == null) {
                Log.e(TAG, "BluetoothAdapter is Null");
                return;
            } else {
                if (!bleAdaptor.isEnabled()) {
                    Log.d(TAG, "BluetoothAdapter is NOT enabled, enable now");
                    bleAdaptor.enable();
                    if (!bleAdaptor.isEnabled()) {
                        Log.e(TAG, "Can't enable Bluetooth");
                        return;
                    }
                }
            }

            mBleScanner = bleAdaptor.getBluetoothLeScanner();
            mScanFilterList = new ArrayList<ScanFilter>();
        }

        /**
         * Function to be called by BleScanReceiver to start
         * Initial Bluetooth scan alarm
         *
         * @param scanMode - scan mode
         * @param startTime - time when the first scan needs to be started
         * @param scanTime - time for the scan is lasted
         * @param noScanTime - time when the scan is stopped
         * @param numAlarms - number of alarms to start and to stop scan
         *
         */
        public void firstAlarm(int scanMode, int startTime, int scanTime,
                               int noScanTime, int numAlarms) {
            Log.d(TAG, "First Alarm for scan mode: " + scanMode);
            mScanTime = scanTime;
            mNoScanTime = noScanTime;
            mNumAlarms = numAlarms;
            mScanSettings = new ScanSettings.Builder().setScanMode(
                                            scanMode).build();

            Intent alarmIntent = new Intent(BleScanListener.BLESCAN);
            alarmIntent.putExtra("com.android.pmc.BLESCAN.Action", START_SCAN);
            alarmIntent.putExtra("com.android.pmc.BLESCAN.CurrentAlarm", INIT_ALARM_NO);
            long triggerTime = SystemClock.elapsedRealtime()
                               + startTime * 1000;
            mAlarmManager.setExactAndAllowWhileIdle(
                          AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime,
                          PendingIntent.getBroadcast(mContext, 0,
                                        alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
        }

        /**
         * Function to be called by onReceive() to start subsequent alarm
         *
         * @param intent - intent to get extra data
         * @param timeInterval - time for alarm to trigger next alarm
         * @param nextAction - next action for the alarm
         *
         */
        public void repeatAlarm(Intent intent, int timeInterval,
                                  int nextAction) {

            int currentAlarm = intent.getIntExtra("com.android.pmc.BLESCAN.CurrentAlarm", 0);
            Log.d(TAG, "repeatAlarm() currentAlarm: " + currentAlarm);
            if (currentAlarm == 0) {
                Log.d(TAG, "Received Alarm with no currentAlarm");
                return;
            }
            if (currentAlarm >= mNumAlarms) {
                Log.d(TAG, "All alarms are done");
                return;
            }
            Log.d(TAG, "Next Action: " + nextAction);
            Intent alarmIntent = new Intent(BleScanListener.BLESCAN);
            alarmIntent.putExtra("com.android.pmc.BLESCAN.Action", nextAction);
            alarmIntent.putExtra("com.android.pmc.BLESCAN.CurrentAlarm", ++currentAlarm);
            long triggerTime = SystemClock.elapsedRealtime()
                                          + timeInterval * 1000;
            mAlarmManager.setExactAndAllowWhileIdle(
                          AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime,
                          PendingIntent.getBroadcast(mContext, 0,
                          alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
        }

        /**
         * Callback will be called for AlarmManager to start Bluetooth LE scan
         *
         * @param context - system will provide a context to this function
         * @param intent - system will provide an intent to this function
         */
        @Override
        public void onReceive(Context context, Intent intent) {
            if (!intent.getAction().equals(BLESCAN)) {
                return;
            }
            int action = intent.getIntExtra("com.android.pmc.BLESCAN.Action", 0);
            Log.d(TAG, "onReceive() Action: " + action);
            if (action == -1) {
                Log.e(TAG, "Received Alarm with no Action");
                return;
            }
            if (action == START_SCAN) {
                Log.v(TAG, "Before Start Scan");
                mBleScanner.startScan(mScanFilterList, mScanSettings,
                                 mScanCallback);
                repeatAlarm(intent, mScanTime, STOP_SCAN);
            } else if (action == STOP_SCAN) {
                Log.v(TAG, "Before Stop scan");
                mBleScanner.stopScan(mScanCallback);
                repeatAlarm(intent, mNoScanTime, START_SCAN);
            } else {
                Log.e(TAG, "Unknown Action");
            }
        }
    }

    /**
     * Constructor to be called by PMC
     *
     * @param context - PMC will provide a context
     * @param alarmManager - PMC will provide alarmManager
     */
    public BleScanReceiver(Context context, AlarmManager alarmManager) {
        // prepare for setting alarm service
        mContext = context;
        mAlarmManager = alarmManager;
        mAlarmScanListener = new BleScanListener();

        // RegisterAlarmReceiver for BleScanListener
        mContext.registerReceiver(mAlarmScanListener,
                new IntentFilter(BleScanListener.BLESCAN));

    }

    /**
     * Method to receive the broadcast from python client
     *
     * @param context - system will provide a context to this function
     * @param intent - system will provide an intent to this function
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(BLE_SCAN_INTENT)) {
            Bundle extras = intent.getExtras();
            int scanMode = -1, startTime = 0, scanTime = 0, noScanTime = 0;
            int repetitions = 1;
            String str;

            if (extras == null) {
                Log.e(TAG, "No parameters specified");
                return;
            }

            if (!extras.containsKey("ScanMode")) {
                Log.e(TAG, "No scan mode specified");
                return;
            }
            str = extras.getString("ScanMode");
            Log.d(TAG, "Scan Mode = " + str);
            scanMode = Integer.valueOf(str);

            if (!extras.containsKey("StartTime")) {
                Log.e(TAG, "No Start Time specified");
                return;
            }
            str = extras.getString("StartTime");
            Log.d(TAG, "Start Time = " + str);
            startTime = Integer.valueOf(str);

            if (!extras.containsKey("ScanTime")) {
                Log.e(TAG, "No Scan Time specified");
                return;
            }
            str = extras.getString("ScanTime");
            Log.d(TAG, "Scan Time = " + str);
            scanTime = Integer.valueOf(str);

            if (extras.containsKey("Repetitions")) {

                str = extras.getString("Repetitions");
                Log.d(TAG, "Repetitions = " + str);
                repetitions = Integer.valueOf(str);

                if (!extras.containsKey("NoScanTime")) {
                    Log.e(TAG, "No NoScan Time specified");
                    return;
                }
                str = extras.getString("NoScanTime");
                Log.d(TAG, "NoScan Time = " + str);
                noScanTime = Integer.valueOf(str);
            }
            if (scanTime == 0 || startTime == 0 || scanMode == -1) {
                Log.d(TAG, "Invalid paramters");
                return;
            }
            mAlarmScanListener.firstAlarm(scanMode, startTime,
                                       scanTime, noScanTime, repetitions * 2);
        }
    }
}
