/*
 * Copyright (C) 2019 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.internal.telephony.metrics;

import static com.android.internal.telephony.metrics.TelephonyMetrics.toCallQualityProto;

import android.telephony.CallQuality;
import android.telephony.CellInfo;
import android.telephony.CellSignalStrengthLte;
import android.telephony.SignalStrength;
import android.util.Pair;

import com.android.internal.telephony.Phone;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.telephony.Rlog;

import java.util.ArrayList;
import java.util.Collections;

/**
 * CallQualityMetrics is a utility for tracking the CallQuality during an ongoing call session. It
 * processes snapshots throughout the call to keep track of info like the best and worst
 * ServiceStates, durations of good and bad quality, and other summary statistics.
 */
public class CallQualityMetrics {

    private static final String TAG = CallQualityMetrics.class.getSimpleName();

    // certain metrics are only logged on userdebug
    private static final boolean IS_DEBUGGABLE = TelephonyUtils.IS_DEBUGGABLE;

    // We only log the first MAX_SNAPSHOTS changes to CallQuality
    private static final int MAX_SNAPSHOTS = 5;

    // value of mCallQualityState which means the CallQuality is EXCELLENT/GOOD/FAIR
    private static final int GOOD_QUALITY = 0;

    // value of mCallQualityState which means the CallQuality is BAD/POOR
    private static final int BAD_QUALITY = 1;

    private Phone mPhone;

    /** Snapshots of the call quality and SignalStrength (LTE-SNR for IMS calls) */
    // mUlSnapshots holds snapshots from uplink call quality changes. We log take snapshots of the
    // first MAX_SNAPSHOTS transitions between good and bad quality
    private ArrayList<Pair<CallQuality, Integer>> mUlSnapshots = new ArrayList<>();
    // mDlSnapshots holds snapshots from downlink call quality changes. We log take snapshots of
    // the first MAX_SNAPSHOTS transitions between good and bad quality
    private ArrayList<Pair<CallQuality, Integer>> mDlSnapshots = new ArrayList<>();

    // holds lightweight history of call quality and durations, used for calculating total time
    // spent with bad and good quality for metrics and bugreports. This is separate from the
    // snapshots because those are capped at MAX_SNAPSHOTS to avoid excessive memory use.
    private ArrayList<TimestampedQualitySnapshot> mFullUplinkQuality = new ArrayList<>();
    private ArrayList<TimestampedQualitySnapshot> mFullDownlinkQuality = new ArrayList<>();

    // Current downlink call quality
    private int mDlCallQualityState = GOOD_QUALITY;

    // Current uplink call quality
    private int mUlCallQualityState = GOOD_QUALITY;

    // The last logged CallQuality
    private CallQuality mLastCallQuality;

    /** Snapshots taken at best and worst SignalStrengths */
    private Pair<CallQuality, Integer> mWorstSsWithGoodDlQuality;
    private Pair<CallQuality, Integer> mBestSsWithGoodDlQuality;
    private Pair<CallQuality, Integer> mWorstSsWithBadDlQuality;
    private Pair<CallQuality, Integer> mBestSsWithBadDlQuality;
    private Pair<CallQuality, Integer> mWorstSsWithGoodUlQuality;
    private Pair<CallQuality, Integer> mBestSsWithGoodUlQuality;
    private Pair<CallQuality, Integer> mWorstSsWithBadUlQuality;
    private Pair<CallQuality, Integer> mBestSsWithBadUlQuality;

    /**
     * Construct a CallQualityMetrics object to be used to keep track of call quality for a single
     * call session.
     */
    public CallQualityMetrics(Phone phone) {
        mPhone = phone;
        mLastCallQuality = new CallQuality();
    }

    /**
     * Called when call quality changes.
     */
    public void saveCallQuality(CallQuality cq) {
        if (cq.getUplinkCallQualityLevel() == CallQuality.CALL_QUALITY_NOT_AVAILABLE
                || cq.getDownlinkCallQualityLevel() == CallQuality.CALL_QUALITY_NOT_AVAILABLE) {
            return;
        }

        // uplink and downlink call quality are tracked separately
        int newUlCallQualityState = BAD_QUALITY;
        int newDlCallQualityState = BAD_QUALITY;
        if (isGoodQuality(cq.getUplinkCallQualityLevel())) {
            newUlCallQualityState = GOOD_QUALITY;
        }
        if (isGoodQuality(cq.getDownlinkCallQualityLevel())) {
            newDlCallQualityState = GOOD_QUALITY;
        }

        if (IS_DEBUGGABLE) {
            if (newUlCallQualityState != mUlCallQualityState) {
                addSnapshot(cq, mUlSnapshots);
            }
            if (newDlCallQualityState != mDlCallQualityState) {
                addSnapshot(cq, mDlSnapshots);
            }
        }

        updateTotalDurations(cq);

        updateMinAndMaxSignalStrengthSnapshots(newDlCallQualityState, newUlCallQualityState, cq);

        mUlCallQualityState = newUlCallQualityState;
        mDlCallQualityState = newDlCallQualityState;
        // call duration updates sometimes come out of order
        if (cq.getCallDuration() > mLastCallQuality.getCallDuration()) {
            mLastCallQuality = cq;
        }
    }

    private void updateTotalDurations(CallQuality cq) {
        mFullDownlinkQuality.add(new TimestampedQualitySnapshot(cq.getCallDuration(),
                cq.getDownlinkCallQualityLevel()));
        mFullUplinkQuality.add(new TimestampedQualitySnapshot(cq.getCallDuration(),
                cq.getUplinkCallQualityLevel()));
    }

    private static boolean isGoodQuality(int callQualityLevel) {
        return callQualityLevel < CallQuality.CALL_QUALITY_BAD;
    }

    /**
     * Save a snapshot of the call quality and signal strength. This can be called with uplink or
     * downlink call quality level.
     */
    private void addSnapshot(CallQuality cq, ArrayList<Pair<CallQuality, Integer>> snapshots) {
        if (snapshots.size() < MAX_SNAPSHOTS) {
            Integer ss = getLteSnr();
            snapshots.add(Pair.create(cq, ss));
        }
    }

    /**
     * Updates the snapshots saved when signal strength is highest and lowest while the call quality
     * is good and bad for both uplink and downlink call quality.
     * <p>
     * At the end of the call we should have:
     *  - for both UL and DL:
     *     - snapshot of the best signal strength with bad call quality
     *     - snapshot of the worst signal strength with bad call quality
     *     - snapshot of the best signal strength with good call quality
     *     - snapshot of the worst signal strength with good call quality
     */
    private void updateMinAndMaxSignalStrengthSnapshots(int newDlCallQualityState,
            int newUlCallQualityState, CallQuality cq) {
        Integer ss = getLteSnr();
        if (ss.equals(CellInfo.UNAVAILABLE)) {
            return;
        }

        // downlink
        if (newDlCallQualityState == GOOD_QUALITY) {
            if (mWorstSsWithGoodDlQuality == null || ss < mWorstSsWithGoodDlQuality.second) {
                mWorstSsWithGoodDlQuality = Pair.create(cq, ss);
            }
            if (mBestSsWithGoodDlQuality == null || ss > mBestSsWithGoodDlQuality.second) {
                mBestSsWithGoodDlQuality = Pair.create(cq, ss);
            }
        } else {
            if (mWorstSsWithBadDlQuality == null || ss < mWorstSsWithBadDlQuality.second) {
                mWorstSsWithBadDlQuality = Pair.create(cq, ss);
            }
            if (mBestSsWithBadDlQuality == null || ss > mBestSsWithBadDlQuality.second) {
                mBestSsWithBadDlQuality = Pair.create(cq, ss);
            }
        }

        // uplink
        if (newUlCallQualityState == GOOD_QUALITY) {
            if (mWorstSsWithGoodUlQuality == null || ss < mWorstSsWithGoodUlQuality.second) {
                mWorstSsWithGoodUlQuality = Pair.create(cq, ss);
            }
            if (mBestSsWithGoodUlQuality == null || ss > mBestSsWithGoodUlQuality.second) {
                mBestSsWithGoodUlQuality = Pair.create(cq, ss);
            }
        } else {
            if (mWorstSsWithBadUlQuality == null || ss < mWorstSsWithBadUlQuality.second) {
                mWorstSsWithBadUlQuality = Pair.create(cq, ss);
            }
            if (mBestSsWithBadUlQuality == null || ss > mBestSsWithBadUlQuality.second) {
                mBestSsWithBadUlQuality = Pair.create(cq, ss);
            }
        }
    }

    // Returns the LTE signal to noise ratio, or 0 if unavailable
    private Integer getLteSnr() {
        ServiceStateTracker sst = mPhone.getDefaultPhone().getServiceStateTracker();
        if (sst == null) {
            Rlog.e(TAG, "getLteSnr: unable to get SST for phone " + mPhone.getPhoneId());
            return CellInfo.UNAVAILABLE;
        }

        SignalStrength ss = sst.getSignalStrength();
        if (ss == null) {
            Rlog.e(TAG, "getLteSnr: unable to get SignalStrength for phone " + mPhone.getPhoneId());
            return CellInfo.UNAVAILABLE;
        }

        // There may be multiple CellSignalStrengthLte, so try to use one with available SNR
        for (CellSignalStrengthLte lteSs : ss.getCellSignalStrengths(CellSignalStrengthLte.class)) {
            int snr = lteSs.getRssnr();
            if (snr != CellInfo.UNAVAILABLE) {
                return snr;
            }
        }

        return CellInfo.UNAVAILABLE;
    }

    private static TelephonyCallSession.Event.SignalStrength toProto(int ss) {
        TelephonyCallSession.Event.SignalStrength ret =
                new TelephonyCallSession.Event.SignalStrength();
        ret.lteSnr = ss;
        return ret;
    }

    /**
     * Return the full downlink CallQualitySummary using the saved CallQuality records.
     */
    public TelephonyCallSession.Event.CallQualitySummary getCallQualitySummaryDl() {
        TelephonyCallSession.Event.CallQualitySummary summary =
                new TelephonyCallSession.Event.CallQualitySummary();
        Pair<Integer, Integer> totalGoodAndBadDurations = getTotalGoodAndBadQualityTimeMs(
                mFullDownlinkQuality);
        summary.totalGoodQualityDurationInSeconds = totalGoodAndBadDurations.first / 1000;
        summary.totalBadQualityDurationInSeconds = totalGoodAndBadDurations.second / 1000;
        // This value could be different from mLastCallQuality.getCallDuration if we support
        // handover from IMS->CS->IMS, but this is currently not possible
        // TODO(b/130302396) this also may be possible when we put a call on hold and continue with
        // another call
        summary.totalDurationWithQualityInformationInSeconds =
                mLastCallQuality.getCallDuration() / 1000;
        if (mWorstSsWithGoodDlQuality != null) {
            summary.snapshotOfWorstSsWithGoodQuality =
                    toCallQualityProto(mWorstSsWithGoodDlQuality.first);
            summary.worstSsWithGoodQuality = toProto(mWorstSsWithGoodDlQuality.second);
        }
        if (mBestSsWithGoodDlQuality != null) {
            summary.snapshotOfBestSsWithGoodQuality =
                    toCallQualityProto(mBestSsWithGoodDlQuality.first);
            summary.bestSsWithGoodQuality = toProto(mBestSsWithGoodDlQuality.second);
        }
        if (mWorstSsWithBadDlQuality != null) {
            summary.snapshotOfWorstSsWithBadQuality =
                    toCallQualityProto(mWorstSsWithBadDlQuality.first);
            summary.worstSsWithBadQuality = toProto(mWorstSsWithBadDlQuality.second);
        }
        if (mBestSsWithBadDlQuality != null) {
            summary.snapshotOfBestSsWithBadQuality =
                    toCallQualityProto(mBestSsWithBadDlQuality.first);
            summary.bestSsWithBadQuality = toProto(mBestSsWithBadDlQuality.second);
        }
        summary.snapshotOfEnd = toCallQualityProto(mLastCallQuality);
        return summary;
    }

    /**
     * Return the full uplink CallQualitySummary using the saved CallQuality records.
     */
    public TelephonyCallSession.Event.CallQualitySummary getCallQualitySummaryUl() {
        TelephonyCallSession.Event.CallQualitySummary summary =
                new TelephonyCallSession.Event.CallQualitySummary();
        Pair<Integer, Integer> totalGoodAndBadDurations = getTotalGoodAndBadQualityTimeMs(
                mFullUplinkQuality);
        summary.totalGoodQualityDurationInSeconds = totalGoodAndBadDurations.first / 1000;
        summary.totalBadQualityDurationInSeconds = totalGoodAndBadDurations.second / 1000;
        // This value could be different from mLastCallQuality.getCallDuration if we support
        // handover from IMS->CS->IMS, but this is currently not possible
        // TODO(b/130302396) this also may be possible when we put a call on hold and continue with
        // another call
        summary.totalDurationWithQualityInformationInSeconds =
                mLastCallQuality.getCallDuration() / 1000;
        if (mWorstSsWithGoodUlQuality != null) {
            summary.snapshotOfWorstSsWithGoodQuality =
                    toCallQualityProto(mWorstSsWithGoodUlQuality.first);
            summary.worstSsWithGoodQuality = toProto(mWorstSsWithGoodUlQuality.second);
        }
        if (mBestSsWithGoodUlQuality != null) {
            summary.snapshotOfBestSsWithGoodQuality =
                    toCallQualityProto(mBestSsWithGoodUlQuality.first);
            summary.bestSsWithGoodQuality = toProto(mBestSsWithGoodUlQuality.second);
        }
        if (mWorstSsWithBadUlQuality != null) {
            summary.snapshotOfWorstSsWithBadQuality =
                    toCallQualityProto(mWorstSsWithBadUlQuality.first);
            summary.worstSsWithBadQuality = toProto(mWorstSsWithBadUlQuality.second);
        }
        if (mBestSsWithBadUlQuality != null) {
            summary.snapshotOfBestSsWithBadQuality =
                    toCallQualityProto(mBestSsWithBadUlQuality.first);
            summary.bestSsWithBadQuality = toProto(mBestSsWithBadUlQuality.second);
        }
        summary.snapshotOfEnd = toCallQualityProto(mLastCallQuality);
        return summary;
    }


    /**
     * Container class for call quality level and signal strength at the time of snapshot. This
     * class implements compareTo so that it can be sorted by timestamp
     */
    private class TimestampedQualitySnapshot implements Comparable<TimestampedQualitySnapshot> {
        int mTimestampMs;
        int mCallQualityLevel;

        TimestampedQualitySnapshot(int timestamp, int cq) {
            mTimestampMs = timestamp;
            mCallQualityLevel = cq;
        }

        @Override
        public int compareTo(TimestampedQualitySnapshot o) {
            return this.mTimestampMs - o.mTimestampMs;
        }

        @Override
        public String toString() {
            return "mTimestampMs=" + mTimestampMs + " mCallQualityLevel=" + mCallQualityLevel;
        }
    }

    /**
     * Use a list of snapshots to calculate and return the total time spent in a call with good
     * quality and bad quality.
     * This is slightly expensive since it involves sorting the snapshots by timestamp.
     *
     * @param snapshots a list of uplink or downlink snapshots
     * @return a pair where the first element is the total good quality time and the second element
     * is the total bad quality time
     */
    private Pair<Integer, Integer> getTotalGoodAndBadQualityTimeMs(
            ArrayList<TimestampedQualitySnapshot> snapshots) {
        int totalGoodQualityTime = 0;
        int totalBadQualityTime = 0;
        int lastTimestamp = 0;
        // sort by timestamp using TimestampedQualitySnapshot.compareTo
        Collections.sort(snapshots);
        for (TimestampedQualitySnapshot snapshot : snapshots) {
            int timeSinceLastSnapshot = snapshot.mTimestampMs - lastTimestamp;
            if (isGoodQuality(snapshot.mCallQualityLevel)) {
                totalGoodQualityTime += timeSinceLastSnapshot;
            } else {
                totalBadQualityTime += timeSinceLastSnapshot;
            }
            lastTimestamp = snapshot.mTimestampMs;
        }

        return Pair.create(totalGoodQualityTime, totalBadQualityTime);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[CallQualityMetrics phone ");
        sb.append(mPhone.getPhoneId());
        sb.append(" mUlSnapshots: {");
        for (Pair<CallQuality, Integer> snapshot : mUlSnapshots) {
            sb.append(" {cq=");
            sb.append(snapshot.first);
            sb.append(" ss=");
            sb.append(snapshot.second);
            sb.append("}");
        }
        sb.append("}");
        sb.append(" mDlSnapshots:{");
        for (Pair<CallQuality, Integer> snapshot : mDlSnapshots) {
            sb.append(" {cq=");
            sb.append(snapshot.first);
            sb.append(" ss=");
            sb.append(snapshot.second);
            sb.append("}");
        }
        sb.append("}");
        sb.append(" ");
        Pair<Integer, Integer> dlTotals = getTotalGoodAndBadQualityTimeMs(mFullDownlinkQuality);
        Pair<Integer, Integer> ulTotals = getTotalGoodAndBadQualityTimeMs(mFullUplinkQuality);
        sb.append(" TotalDlGoodQualityTimeMs: ");
        sb.append(dlTotals.first);
        sb.append(" TotalDlBadQualityTimeMs: ");
        sb.append(dlTotals.second);
        sb.append(" TotalUlGoodQualityTimeMs: ");
        sb.append(ulTotals.first);
        sb.append(" TotalUlBadQualityTimeMs: ");
        sb.append(ulTotals.second);
        sb.append("]");
        return sb.toString();
    }
}
