/*
 * Copyright (C) 2018 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.location;

import android.annotation.FloatRange;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.Preconditions;

/**
 * A container with measurement corrections for a single visible satellite
 *
 * @hide
 */
@SystemApi
public final class GnssSingleSatCorrection implements Parcelable {

    /**
     * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
     * #mProbSatIsLos}.
     *
     * @hide
     */
    public static final int HAS_PROB_SAT_IS_LOS_MASK = 1 << 0;

    /**
     * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
     * #mExcessPathLengthMeters}.
     *
     * @hide
     */
    public static final int HAS_EXCESS_PATH_LENGTH_MASK = 1 << 1;

    /**
     * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
     * #mExcessPathLengthUncertaintyMeters}.
     *
     * @hide
     */
    public static final int HAS_EXCESS_PATH_LENGTH_UNC_MASK = 1 << 2;

    /**
     * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
     * #mReflectingPlane}.
     *
     * @hide
     */
    public static final int HAS_REFLECTING_PLANE_MASK = 1 << 3;

    /** A bitmask of fields present in this object (see HAS_* constants defined above) */
    private final int mSingleSatCorrectionFlags;

    /** Defines the constellation of the given satellite as defined in {@link GnssStatus}. */
    @GnssStatus.ConstellationType
    private final int mConstellationType;

    /**
     * Satellite vehicle ID number
     *
     * <p>Interpretation depends on {@link GnssStatus#getSvid(int)}.
     */
    @IntRange(from = 0)
    private final int mSatId;

    /**
     * Carrier frequency of the signal to be corrected, for example it can be the GPS center
     * frequency for L1 = 1,575,420,000 Hz, varying GLO channels, etc.
     *
     * <p>For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two correction
     * objects will be reported for this same satellite, in one of the correction objects, all the
     * values related to L1 will be filled, and in the other all of the values related to L5 will be
     * filled.
     */
    @FloatRange(from = 0.0f,  fromInclusive = false)
    private final float mCarrierFrequencyHz;

    /**
     * The probability that the satellite is estimated to be in Line-of-Sight condition at the given
     * location.
     */
    @FloatRange(from = 0.0f, to = 1.0f)
    private final float mProbSatIsLos;

    /**
     * Excess path length to be subtracted from pseudorange before using it in calculating location.
     */
    @FloatRange(from = 0.0f)
    private final float mExcessPathLengthMeters;

    /** Error estimate (1-sigma) for the Excess path length estimate */
    @FloatRange(from = 0.0f)
    private final float mExcessPathLengthUncertaintyMeters;

    /**
     * Defines the reflecting plane location and azimuth information
     *
     * <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite
     * signal goes through multiple reflections or if reflection plane serving is not supported.
     */
    @Nullable
    private final GnssReflectingPlane mReflectingPlane;

    private GnssSingleSatCorrection(Builder builder) {
        mSingleSatCorrectionFlags = builder.mSingleSatCorrectionFlags;
        mSatId = builder.mSatId;
        mConstellationType = builder.mConstellationType;
        mCarrierFrequencyHz = builder.mCarrierFrequencyHz;
        mProbSatIsLos = builder.mProbSatIsLos;
        mExcessPathLengthMeters = builder.mExcessPathLengthMeters;
        mExcessPathLengthUncertaintyMeters = builder.mExcessPathLengthUncertaintyMeters;
        mReflectingPlane = builder.mReflectingPlane;
    }

    /**
     * Gets a bitmask of fields present in this object
     *
     * @hide
     */
    public int getSingleSatelliteCorrectionFlags() {
        return mSingleSatCorrectionFlags;
    }

    /**
     * Gets the constellation type.
     *
     * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in {@link
     * GnssStatus}.
     */
    @GnssStatus.ConstellationType
    public int getConstellationType() {
        return mConstellationType;
    }

    /**
     * Gets the satellite ID.
     *
     * <p>Interpretation depends on {@link #getConstellationType()}. See {@link
     * GnssStatus#getSvid(int)}.
     */
    @IntRange(from = 0)
    public int getSatelliteId() {
        return mSatId;
    }

    /**
     * Gets the carrier frequency of the tracked signal.
     *
     * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
     * L5 = 1176.45 MHz, varying GLO channels, etc.
     *
     * <p>For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two correction
     * objects will be reported for this same satellite, in one of the correction objects, all the
     * values related to L1 will be filled, and in the other all of the values related to L5 will be
     * filled.
     *
     * @return the carrier frequency of the signal tracked in Hz.
     */
    @FloatRange(from = 0.0f,  fromInclusive = false)
    public float getCarrierFrequencyHz() {
        return mCarrierFrequencyHz;
    }

    /**
     * Returns the probability that the satellite is in line-of-sight condition at the given
     * location.
     */
    @FloatRange(from = 0.0f, to = 1.0f)
    public float getProbabilityLineOfSight() {
        return mProbSatIsLos;
    }

    /**
     * Returns the Excess path length to be subtracted from pseudorange before using it in
     * calculating location.
     */
    @FloatRange(from = 0.0f)
    public float getExcessPathLengthMeters() {
        return mExcessPathLengthMeters;
    }

    /** Returns the error estimate (1-sigma) for the Excess path length estimate */
    @FloatRange(from = 0.0f)
    public float getExcessPathLengthUncertaintyMeters() {
        return mExcessPathLengthUncertaintyMeters;
    }

    /**
     * Returns the reflecting plane characteristics at which the signal has bounced
     *
     * <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite
     * signal goes through multiple reflections or if reflection plane serving is not supported
     */
    @Nullable
    public GnssReflectingPlane getReflectingPlane() {
        return mReflectingPlane;
    }

    /** Returns {@code true} if {@link #getProbabilityLineOfSight()} is valid. */
    public boolean hasValidSatelliteLineOfSight() {
        return (mSingleSatCorrectionFlags & HAS_PROB_SAT_IS_LOS_MASK) != 0;
    }

    /** Returns {@code true} if {@link #getExcessPathLengthMeters()} is valid. */
    public boolean hasExcessPathLength() {
        return (mSingleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_MASK) != 0;
    }

    /** Returns {@code true} if {@link #getExcessPathLengthUncertaintyMeters()} is valid. */
    public boolean hasExcessPathLengthUncertainty() {
        return (mSingleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_UNC_MASK) != 0;
    }

    /** Returns {@code true} if {@link #getReflectingPlane()} is valid. */
    public boolean hasReflectingPlane() {
        return (mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0;
    }

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

    public static final Creator<GnssSingleSatCorrection> CREATOR =
            new Creator<GnssSingleSatCorrection>() {
                @Override
                @NonNull
                public GnssSingleSatCorrection createFromParcel(@NonNull Parcel parcel) {
                    int mSingleSatCorrectionFlags = parcel.readInt();
                    boolean hasReflectingPlane =
                            (mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0;
                    final GnssSingleSatCorrection.Builder singleSatCorrectionBuilder =
                            new Builder()
                                    .setConstellationType(parcel.readInt())
                                    .setSatelliteId(parcel.readInt())
                                    .setCarrierFrequencyHz(parcel.readFloat())
                                    .setProbabilityLineOfSight(parcel.readFloat())
                                    .setExcessPathLengthMeters(parcel.readFloat())
                                    .setExcessPathLengthUncertaintyMeters(parcel.readFloat());
                    if (hasReflectingPlane) {
                        singleSatCorrectionBuilder.setReflectingPlane(
                                GnssReflectingPlane.CREATOR.createFromParcel(parcel));
                    }
                    return singleSatCorrectionBuilder.build();
                }

                @Override
                public GnssSingleSatCorrection[] newArray(int i) {
                    return new GnssSingleSatCorrection[i];
                }
            };

    @Override
    public String toString() {
        final String format = "   %-29s = %s\n";
        StringBuilder builder = new StringBuilder("GnssSingleSatCorrection:\n");
        builder.append(
                String.format(format, "SingleSatCorrectionFlags = ", mSingleSatCorrectionFlags));
        builder.append(String.format(format, "ConstellationType = ", mConstellationType));
        builder.append(String.format(format, "SatId = ", mSatId));
        builder.append(String.format(format, "CarrierFrequencyHz = ", mCarrierFrequencyHz));
        builder.append(String.format(format, "ProbSatIsLos = ", mProbSatIsLos));
        builder.append(String.format(format, "ExcessPathLengthMeters = ", mExcessPathLengthMeters));
        builder.append(
                String.format(
                        format,
                        "ExcessPathLengthUncertaintyMeters = ",
                        mExcessPathLengthUncertaintyMeters));
        if (hasReflectingPlane()) {
            builder.append(String.format(format, "ReflectingPlane = ", mReflectingPlane));
        }
        return builder.toString();
    }

    @Override
    public void writeToParcel(@NonNull Parcel parcel, int flags) {
        parcel.writeInt(mSingleSatCorrectionFlags);
        parcel.writeInt(mConstellationType);
        parcel.writeInt(mSatId);
        parcel.writeFloat(mCarrierFrequencyHz);
        parcel.writeFloat(mProbSatIsLos);
        parcel.writeFloat(mExcessPathLengthMeters);
        parcel.writeFloat(mExcessPathLengthUncertaintyMeters);
        if (hasReflectingPlane()) {
            mReflectingPlane.writeToParcel(parcel, flags);
        }
    }

    /** Builder for {@link GnssSingleSatCorrection} */
    public static final class Builder {

        /**
         * For documentation of below fields, see corresponding fields in {@link
         * GnssSingleSatCorrection}.
         */
        private int mSingleSatCorrectionFlags;

        private int mConstellationType;
        private int mSatId;
        private float mCarrierFrequencyHz;
        private float mProbSatIsLos;
        private float mExcessPathLengthMeters;
        private float mExcessPathLengthUncertaintyMeters;
        @Nullable
        private GnssReflectingPlane mReflectingPlane;

        /** Sets the constellation type. */
        @NonNull public Builder setConstellationType(
                @GnssStatus.ConstellationType int constellationType) {
            mConstellationType = constellationType;
            return this;
        }

        /** Sets the Satellite ID defined in the ICD of the given constellation. */
        @NonNull public Builder setSatelliteId(@IntRange(from = 0) int satId) {
            mSatId = satId;
            return this;
        }

        /** Sets the Carrier frequency in Hz. */
        @NonNull public Builder setCarrierFrequencyHz(
                @FloatRange(from = 0.0f,  fromInclusive = false) float carrierFrequencyHz) {
            mCarrierFrequencyHz = carrierFrequencyHz;
            return this;
        }

        /**
         * Sets the line-of-sight probability of the satellite at the given location in the range
         * between 0 and 1.
         */
        @NonNull public Builder setProbabilityLineOfSight(
                @FloatRange(from = 0.0f, to = 1.0f) float probSatIsLos) {
            Preconditions.checkArgumentInRange(
                    probSatIsLos, 0, 1, "probSatIsLos should be between 0 and 1.");
            mProbSatIsLos = probSatIsLos;
            mSingleSatCorrectionFlags =
                    (byte) (mSingleSatCorrectionFlags | HAS_PROB_SAT_IS_LOS_MASK);
            return this;
        }

        /**
         * Sets the Excess path length to be subtracted from pseudorange before using it in
         * calculating location.
         */
        @NonNull public Builder setExcessPathLengthMeters(
                @FloatRange(from = 0.0f) float excessPathLengthMeters) {
            mExcessPathLengthMeters = excessPathLengthMeters;
            mSingleSatCorrectionFlags =
                    (byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_MASK);
            return this;
        }

        /** Sets the error estimate (1-sigma) for the Excess path length estimate */
        @NonNull public Builder setExcessPathLengthUncertaintyMeters(
                @FloatRange(from = 0.0f) float excessPathLengthUncertaintyMeters) {
            mExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters;
            mSingleSatCorrectionFlags =
                    (byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_UNC_MASK);
            return this;
        }

        /** Sets the reflecting plane information */
        @NonNull public Builder setReflectingPlane(@Nullable GnssReflectingPlane reflectingPlane) {
            mReflectingPlane = reflectingPlane;
            if (reflectingPlane != null) {
                mSingleSatCorrectionFlags =
                        (byte) (mSingleSatCorrectionFlags | HAS_REFLECTING_PLANE_MASK);
            } else {
                mSingleSatCorrectionFlags =
                        (byte) (mSingleSatCorrectionFlags & ~HAS_REFLECTING_PLANE_MASK);
            }
            return this;
        }

        /** Builds a {@link GnssSingleSatCorrection} instance as specified by this builder. */
        @NonNull public GnssSingleSatCorrection build() {
            return new GnssSingleSatCorrection(this);
        }
    }
}
