/*
 * 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;
    // Use PMCStatusLogger to send status and start & end times back to Python client
    private PMCStatusLogger mPMCStatusLogger;
    // Test start time is set when receiving the broadcast message from Python client
    private long mStartTestTime;

    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;
        private int mFirstScanTime;
        private long mScanStartTime;
        private long mScanEndTime;

        /**
         * Constructor
         *
         */
        public BleScanListener() {
            Log.d(TAG, "Start 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>();
            Log.d(TAG, "End BleScanListener()");
        }

        /**
         * 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;
            mFirstScanTime = startTime;

            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) {
                mPMCStatusLogger.flash();  // To flash out timestamps into log file
                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");
                mScanStartTime = System.currentTimeMillis();
                mBleScanner.startScan(mScanFilterList, mScanSettings,
                                 mScanCallback);
                repeatAlarm(intent, mScanTime, STOP_SCAN);
            } else if (action == STOP_SCAN) {
                Log.v(TAG, "Before Stop scan");
                mScanEndTime = System.currentTimeMillis();
                mPMCStatusLogger.logAlarmTimes(mScanStartTime / 1000.0, mScanEndTime / 1000.0);
                mBleScanner.stopScan(mScanCallback);
                if ((mScanEndTime - mStartTestTime)
                        < ((mScanTime + mNoScanTime) * mNumAlarms / 2 + mFirstScanTime) * 1000) {
                    repeatAlarm(intent, mNoScanTime, START_SCAN);
                } else {
                    mPMCStatusLogger.flash();  // To flash out timestamps into log file
                    Log.d(TAG, "Time is up to end");
                }
            } 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;

            mStartTestTime = System.currentTimeMillis();
            mPMCStatusLogger = new PMCStatusLogger(TAG + ".log", TAG);

            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);
            if (mBleScanner != null && mScanFilterList != null && mScanSettings != null
                                 && mScanCallback != null) {
                mPMCStatusLogger.logStatus("READY");
            } else {
                Log.e(TAG, "BLE scanner is not ready to start test");
            }
        }
    }
}
