/*
 * 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.BluetoothDevice;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * The {@link AdvertisingSetParameters} provide a way to adjust advertising
 * preferences for each
 * Bluetooth LE advertising set. Use {@link AdvertisingSetParameters.Builder} to
 * create an
 * instance of this class.
 */
public final class AdvertisingSetParameters implements Parcelable {

    /**
     * Advertise on low frequency, around every 1000ms. This is the default and
     * preferred advertising mode as it consumes the least power.
     */
    public static final int INTERVAL_HIGH = 1600;

    /**
     * Advertise on medium frequency, around every 250ms. This is balanced
     * between advertising frequency and power consumption.
     */
    public static final int INTERVAL_MEDIUM = 400;

    /**
     * Perform high frequency, low latency advertising, around every 100ms. This
     * has the highest power consumption and should not be used for continuous
     * background advertising.
     */
    public static final int INTERVAL_LOW = 160;

    /**
     * Minimum value for advertising interval.
     */
    public static final int INTERVAL_MIN = 160;

    /**
     * Maximum value for advertising interval.
     */
    public static final int INTERVAL_MAX = 16777215;

    /**
     * Advertise using the lowest transmission (TX) power level. Low transmission
     * power can be used to restrict the visibility range of advertising packets.
     */
    public static final int TX_POWER_ULTRA_LOW = -21;

    /**
     * Advertise using low TX power level.
     */
    public static final int TX_POWER_LOW = -15;

    /**
     * Advertise using medium TX power level.
     */
    public static final int TX_POWER_MEDIUM = -7;

    /**
     * Advertise using high TX power level. This corresponds to largest visibility
     * range of the advertising packet.
     */
    public static final int TX_POWER_HIGH = 1;

    /**
     * Minimum value for TX power.
     */
    public static final int TX_POWER_MIN = -127;

    /**
     * Maximum value for TX power.
     */
    public static final int TX_POWER_MAX = 1;

    /**
     * The maximum limited advertisement duration as specified by the Bluetooth
     * SIG
     */
    private static final int LIMITED_ADVERTISING_MAX_MILLIS = 180 * 1000;

    private final boolean mIsLegacy;
    private final boolean mIsAnonymous;
    private final boolean mIncludeTxPower;
    private final int mPrimaryPhy;
    private final int mSecondaryPhy;
    private final boolean mConnectable;
    private final boolean mScannable;
    private final int mInterval;
    private final int mTxPowerLevel;

    private AdvertisingSetParameters(boolean connectable, boolean scannable, boolean isLegacy,
            boolean isAnonymous, boolean includeTxPower,
            int primaryPhy, int secondaryPhy,
            int interval, int txPowerLevel) {
        mConnectable = connectable;
        mScannable = scannable;
        mIsLegacy = isLegacy;
        mIsAnonymous = isAnonymous;
        mIncludeTxPower = includeTxPower;
        mPrimaryPhy = primaryPhy;
        mSecondaryPhy = secondaryPhy;
        mInterval = interval;
        mTxPowerLevel = txPowerLevel;
    }

    private AdvertisingSetParameters(Parcel in) {
        mConnectable = in.readInt() != 0;
        mScannable = in.readInt() != 0;
        mIsLegacy = in.readInt() != 0;
        mIsAnonymous = in.readInt() != 0;
        mIncludeTxPower = in.readInt() != 0;
        mPrimaryPhy = in.readInt();
        mSecondaryPhy = in.readInt();
        mInterval = in.readInt();
        mTxPowerLevel = in.readInt();
    }

    /**
     * Returns whether the advertisement will be connectable.
     */
    public boolean isConnectable() {
        return mConnectable;
    }

    /**
     * Returns whether the advertisement will be scannable.
     */
    public boolean isScannable() {
        return mScannable;
    }

    /**
     * Returns whether the legacy advertisement will be used.
     */
    public boolean isLegacy() {
        return mIsLegacy;
    }

    /**
     * Returns whether the advertisement will be anonymous.
     */
    public boolean isAnonymous() {
        return mIsAnonymous;
    }

    /**
     * Returns whether the TX Power will be included.
     */
    public boolean includeTxPower() {
        return mIncludeTxPower;
    }

    /**
     * Returns the primary advertising phy.
     */
    public int getPrimaryPhy() {
        return mPrimaryPhy;
    }

    /**
     * Returns the secondary advertising phy.
     */
    public int getSecondaryPhy() {
        return mSecondaryPhy;
    }

    /**
     * Returns the advertising interval.
     */
    public int getInterval() {
        return mInterval;
    }

    /**
     * Returns the TX power level for advertising.
     */
    public int getTxPowerLevel() {
        return mTxPowerLevel;
    }

    @Override
    public String toString() {
        return "AdvertisingSetParameters [connectable=" + mConnectable
                + ", isLegacy=" + mIsLegacy
                + ", isAnonymous=" + mIsAnonymous
                + ", includeTxPower=" + mIncludeTxPower
                + ", primaryPhy=" + mPrimaryPhy
                + ", secondaryPhy=" + mSecondaryPhy
                + ", interval=" + mInterval
                + ", txPowerLevel=" + mTxPowerLevel + "]";
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mConnectable ? 1 : 0);
        dest.writeInt(mScannable ? 1 : 0);
        dest.writeInt(mIsLegacy ? 1 : 0);
        dest.writeInt(mIsAnonymous ? 1 : 0);
        dest.writeInt(mIncludeTxPower ? 1 : 0);
        dest.writeInt(mPrimaryPhy);
        dest.writeInt(mSecondaryPhy);
        dest.writeInt(mInterval);
        dest.writeInt(mTxPowerLevel);
    }

    public static final Parcelable.Creator<AdvertisingSetParameters> CREATOR =
            new Creator<AdvertisingSetParameters>() {
                @Override
                public AdvertisingSetParameters[] newArray(int size) {
                    return new AdvertisingSetParameters[size];
                }

                @Override
                public AdvertisingSetParameters createFromParcel(Parcel in) {
                    return new AdvertisingSetParameters(in);
                }
            };

    /**
     * Builder class for {@link AdvertisingSetParameters}.
     */
    public static final class Builder {
        private boolean mConnectable = false;
        private boolean mScannable = false;
        private boolean mIsLegacy = false;
        private boolean mIsAnonymous = false;
        private boolean mIncludeTxPower = false;
        private int mPrimaryPhy = BluetoothDevice.PHY_LE_1M;
        private int mSecondaryPhy = BluetoothDevice.PHY_LE_1M;
        private int mInterval = INTERVAL_LOW;
        private int mTxPowerLevel = TX_POWER_MEDIUM;

        /**
         * Set whether the advertisement type should be connectable or
         * non-connectable.
         * Legacy advertisements can be both connectable and scannable. Non-legacy
         * advertisements can be only scannable or only connectable.
         *
         * @param connectable Controls whether the advertisement type will be connectable (true) or
         * non-connectable (false).
         */
        public Builder setConnectable(boolean connectable) {
            mConnectable = connectable;
            return this;
        }

        /**
         * Set whether the advertisement type should be scannable.
         * Legacy advertisements can be both connectable and scannable. Non-legacy
         * advertisements can be only scannable or only connectable.
         *
         * @param scannable Controls whether the advertisement type will be scannable (true) or
         * non-scannable (false).
         */
        public Builder setScannable(boolean scannable) {
            mScannable = scannable;
            return this;
        }

        /**
         * When set to true, advertising set will advertise 4.x Spec compliant
         * advertisements.
         *
         * @param isLegacy whether legacy advertising mode should be used.
         */
        public Builder setLegacyMode(boolean isLegacy) {
            mIsLegacy = isLegacy;
            return this;
        }

        /**
         * Set whether advertiser address should be ommited from all packets. If this
         * mode is used, periodic advertising can't be enabled for this set.
         *
         * This is used only if legacy mode is not used.
         *
         * @param isAnonymous whether anonymous advertising should be used.
         */
        public Builder setAnonymous(boolean isAnonymous) {
            mIsAnonymous = isAnonymous;
            return this;
        }

        /**
         * Set whether TX power should be included in the extended header.
         *
         * This is used only if legacy mode is not used.
         *
         * @param includeTxPower whether TX power should be included in extended header
         */
        public Builder setIncludeTxPower(boolean includeTxPower) {
            mIncludeTxPower = includeTxPower;
            return this;
        }

        /**
         * Set the primary physical channel used for this advertising set.
         *
         * This is used only if legacy mode is not used.
         *
         * Use {@link BluetoothAdapter#isLeCodedPhySupported} to determine if LE Coded PHY is
         * supported on this device.
         *
         * @param primaryPhy Primary advertising physical channel, can only be {@link
         * BluetoothDevice#PHY_LE_1M} or {@link BluetoothDevice#PHY_LE_CODED}.
         * @throws IllegalArgumentException If the primaryPhy is invalid.
         */
        public Builder setPrimaryPhy(int primaryPhy) {
            if (primaryPhy != BluetoothDevice.PHY_LE_1M
                    && primaryPhy != BluetoothDevice.PHY_LE_CODED) {
                throw new IllegalArgumentException("bad primaryPhy " + primaryPhy);
            }
            mPrimaryPhy = primaryPhy;
            return this;
        }

        /**
         * Set the secondary physical channel used for this advertising set.
         *
         * This is used only if legacy mode is not used.
         *
         * Use {@link BluetoothAdapter#isLeCodedPhySupported} and
         * {@link BluetoothAdapter#isLe2MPhySupported} to determine if LE Coded PHY or 2M PHY is
         * supported on this device.
         *
         * @param secondaryPhy Secondary advertising physical channel, can only be one of {@link
         * BluetoothDevice#PHY_LE_1M}, {@link BluetoothDevice#PHY_LE_2M} or {@link
         * BluetoothDevice#PHY_LE_CODED}.
         * @throws IllegalArgumentException If the secondaryPhy is invalid.
         */
        public Builder setSecondaryPhy(int secondaryPhy) {
            if (secondaryPhy != BluetoothDevice.PHY_LE_1M
                    && secondaryPhy != BluetoothDevice.PHY_LE_2M
                    && secondaryPhy != BluetoothDevice.PHY_LE_CODED) {
                throw new IllegalArgumentException("bad secondaryPhy " + secondaryPhy);
            }
            mSecondaryPhy = secondaryPhy;
            return this;
        }

        /**
         * Set advertising interval.
         *
         * @param interval Bluetooth LE Advertising interval, in 0.625ms unit. Valid range is from
         * 160 (100ms) to 16777215 (10,485.759375 s). Recommended values are: {@link
         * AdvertisingSetParameters#INTERVAL_LOW}, {@link AdvertisingSetParameters#INTERVAL_MEDIUM},
         * or {@link AdvertisingSetParameters#INTERVAL_HIGH}.
         * @throws IllegalArgumentException If the interval is invalid.
         */
        public Builder setInterval(int interval) {
            if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
                throw new IllegalArgumentException("unknown interval " + interval);
            }
            mInterval = interval;
            return this;
        }

        /**
         * Set the transmission power level for the advertising.
         *
         * @param txPowerLevel Transmission power of Bluetooth LE Advertising, in dBm. The valid
         * range is [-127, 1] Recommended values are:
         * {@link AdvertisingSetParameters#TX_POWER_ULTRA_LOW},
         * {@link AdvertisingSetParameters#TX_POWER_LOW},
         * {@link AdvertisingSetParameters#TX_POWER_MEDIUM},
         * or {@link AdvertisingSetParameters#TX_POWER_HIGH}.
         * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
         */
        public Builder setTxPowerLevel(int txPowerLevel) {
            if (txPowerLevel < TX_POWER_MIN || txPowerLevel > TX_POWER_MAX) {
                throw new IllegalArgumentException("unknown txPowerLevel " + txPowerLevel);
            }
            mTxPowerLevel = txPowerLevel;
            return this;
        }

        /**
         * Build the {@link AdvertisingSetParameters} object.
         *
         * @throws IllegalStateException if invalid combination of parameters is used.
         */
        public AdvertisingSetParameters build() {
            if (mIsLegacy) {
                if (mIsAnonymous) {
                    throw new IllegalArgumentException("Legacy advertising can't be anonymous");
                }

                if (mConnectable && !mScannable) {
                    throw new IllegalStateException(
                            "Legacy advertisement can't be connectable and non-scannable");
                }

                if (mIncludeTxPower) {
                    throw new IllegalStateException(
                            "Legacy advertising can't include TX power level in header");
                }
            } else {
                if (mConnectable && mScannable) {
                    throw new IllegalStateException(
                            "Advertising can't be both connectable and scannable");
                }

                if (mIsAnonymous && mConnectable) {
                    throw new IllegalStateException(
                            "Advertising can't be both connectable and anonymous");
                }
            }

            return new AdvertisingSetParameters(mConnectable, mScannable, mIsLegacy, mIsAnonymous,
                    mIncludeTxPower, mPrimaryPhy, mSecondaryPhy, mInterval, mTxPowerLevel);
        }
    }
}
