/*
 * 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 android.bluetooth.le;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManager;
import android.os.RemoteException;
import android.util.Log;

/**
 * This class provides a way to control single Bluetooth LE advertising instance.
 * <p>
 * To get an instance of {@link AdvertisingSet}, call the
 * {@link BluetoothLeAdvertiser#startAdvertisingSet} method.
 * <p>
 * <b>Note:</b> Most of the methods here require {@link android.Manifest.permission#BLUETOOTH_ADMIN}
 * permission.
 *
 * @see AdvertiseData
 */
public final class AdvertisingSet {
    private static final String TAG = "AdvertisingSet";

    private final IBluetoothGatt mGatt;
    private int mAdvertiserId;

    /* package */ AdvertisingSet(int advertiserId,
            IBluetoothManager bluetoothManager) {
        mAdvertiserId = advertiserId;

        try {
            mGatt = bluetoothManager.getBluetoothGatt();
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
            throw new IllegalStateException("Failed to get Bluetooth");
        }
    }

    /* package */ void setAdvertiserId(int advertiserId) {
        mAdvertiserId = advertiserId;
    }

    /**
     * Enables Advertising. This method returns immediately, the operation status is
     * delivered through {@code callback.onAdvertisingEnabled()}.
     * <p>
     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
     *
     * @param enable whether the advertising should be enabled (true), or disabled (false)
     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
     * (655,350 ms)
     * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
     * controller shall attempt to send prior to terminating the extended advertising, even if the
     * duration has not expired. Valid range is from 1 to 255.
     */
    public void enableAdvertising(boolean enable, int duration,
            int maxExtendedAdvertisingEvents) {
        try {
            mGatt.enableAdvertisingSet(mAdvertiserId, enable, duration,
                    maxExtendedAdvertisingEvents);
        } catch (RemoteException e) {
            Log.e(TAG, "remote exception - ", e);
        }
    }

    /**
     * Set/update data being Advertised. Make sure that data doesn't exceed the size limit for
     * specified AdvertisingSetParameters. This method returns immediately, the operation status is
     * delivered through {@code callback.onAdvertisingDataSet()}.
     * <p>
     * Advertising data must be empty if non-legacy scannable advertising is used.
     *
     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
     * three bytes will be added for flags. If the update takes place when the advertising set is
     * enabled, the data can be maximum 251 bytes long.
     */
    public void setAdvertisingData(AdvertiseData advertiseData) {
        try {
            mGatt.setAdvertisingData(mAdvertiserId, advertiseData);
        } catch (RemoteException e) {
            Log.e(TAG, "remote exception - ", e);
        }
    }

    /**
     * Set/update scan response data. Make sure that data doesn't exceed the size limit for
     * specified AdvertisingSetParameters. This method returns immediately, the operation status
     * is delivered through {@code callback.onScanResponseDataSet()}.
     *
     * @param scanResponse Scan response associated with the advertisement data. Size must not
     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes place
     * when the advertising set is enabled, the data can be maximum 251 bytes long.
     */
    public void setScanResponseData(AdvertiseData scanResponse) {
        try {
            mGatt.setScanResponseData(mAdvertiserId, scanResponse);
        } catch (RemoteException e) {
            Log.e(TAG, "remote exception - ", e);
        }
    }

    /**
     * Update advertising parameters associated with this AdvertisingSet. Must be called when
     * advertising is not active. This method returns immediately, the operation status is delivered
     * through {@code callback.onAdvertisingParametersUpdated}.
     *
     * @param parameters advertising set parameters.
     */
    public void setAdvertisingParameters(AdvertisingSetParameters parameters) {
        try {
            mGatt.setAdvertisingParameters(mAdvertiserId, parameters);
        } catch (RemoteException e) {
            Log.e(TAG, "remote exception - ", e);
        }
    }

    /**
     * Update periodic advertising parameters associated with this set. Must be called when
     * periodic advertising is not enabled. This method returns immediately, the operation
     * status is delivered through {@code callback.onPeriodicAdvertisingParametersUpdated()}.
     */
    public void setPeriodicAdvertisingParameters(PeriodicAdvertisingParameters parameters) {
        try {
            mGatt.setPeriodicAdvertisingParameters(mAdvertiserId, parameters);
        } catch (RemoteException e) {
            Log.e(TAG, "remote exception - ", e);
        }
    }

    /**
     * Used to set periodic advertising data, must be called after setPeriodicAdvertisingParameters,
     * or after advertising was started with periodic advertising data set. This method returns
     * immediately, the operation status is delivered through
     * {@code callback.onPeriodicAdvertisingDataSet()}.
     *
     * @param periodicData Periodic advertising data. Size must not exceed {@link
     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes place when the
     * periodic advertising is enabled for this set, the data can be maximum 251 bytes long.
     */
    public void setPeriodicAdvertisingData(AdvertiseData periodicData) {
        try {
            mGatt.setPeriodicAdvertisingData(mAdvertiserId, periodicData);
        } catch (RemoteException e) {
            Log.e(TAG, "remote exception - ", e);
        }
    }

    /**
     * Used to enable/disable periodic advertising. This method returns immediately, the operation
     * status is delivered through {@code callback.onPeriodicAdvertisingEnable()}.
     *
     * @param enable whether the periodic advertising should be enabled (true), or disabled
     * (false).
     */
    public void setPeriodicAdvertisingEnabled(boolean enable) {
        try {
            mGatt.setPeriodicAdvertisingEnable(mAdvertiserId, enable);
        } catch (RemoteException e) {
            Log.e(TAG, "remote exception - ", e);
        }
    }

    /**
     * Returns address associated with this advertising set.
     * This method is exposed only for Bluetooth PTS tests, no app or system service
     * should ever use it.
     *
     * This method requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission.
     *
     * @hide
     */
    public void getOwnAddress() {
        try {
            mGatt.getOwnAddress(mAdvertiserId);
        } catch (RemoteException e) {
            Log.e(TAG, "remote exception - ", e);
        }
    }

    /**
     * Returns advertiserId associated with this advertising set.
     *
     * @hide
     */
    public int getAdvertiserId() {
        return mAdvertiserId;
    }
}
