// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    crate::{estimator::OSCILLATOR_ERROR_STD_DEV_PPM, time_source::Sample},
    anyhow::{anyhow, Error},
    fuchsia_zircon as zx,
    lazy_static::lazy_static,
    time_util::Transform,
};

/// One million for PPM calculations
const MILLION: u64 = 1_000_000;

lazy_static! {
    /// The variance (i.e. standard deviation squared) of the system oscillator frequency error,
    /// used to control the growth in uncertainty during the prediction phase.
    static ref OSCILLATOR_ERROR_VARIANCE: f64 =
        (OSCILLATOR_ERROR_STD_DEV_PPM as f64 / MILLION as f64).powi(2);
}

/// The minimum covariance allowed for the UTC estimate in nanoseconds squared. This helps the
/// kalman filter not drink its own bathwater after receiving very low uncertainly updates from a
/// time source (i.e. become so confident in its internal estimate that it effectively stops
/// accepting new information).
const MIN_COVARIANCE: f64 = 1e12;

/// The factor to apply to standard deviations when producing an error bound. The current setting of
/// two sigma approximately corresponds to a 95% confidence interval.
const ERROR_BOUND_FACTOR: u32 = 2;

/// Converts a zx::Duration to a floating point number of nanoseconds.
fn duration_to_f64(duration: zx::Duration) -> f64 {
    duration.into_nanos() as f64
}

/// Converts a floating point number of nanoseconds to a zx::Duration.
fn f64_to_duration(float: f64) -> zx::Duration {
    zx::Duration::from_nanos(float as i64)
}

/// Maintains an estimate of the offset between true UTC time and monotonic time on this
/// device, based on time samples received from one or more time sources.
///
/// The UTC estimate is implemented as a two dimensional Kalman filter where
///    state vector = [estimated_utc, estimated_frequency]
///
/// estimated_utc is maintained as f64 nanoseconds since a reference UTC (initialized as the first
/// UTC received by the filter). This keeps the absolute values and therefore the floating point
/// exponents lower than if we worked with time since UNIX epoch, so minimizes floating point
/// conversion errors. The filter can run for ~100 days from the reference point before a conversion
/// error of 1ns can occur.
///
/// estimated_frequency is considered a fixed value by the filter, i.e. has a covariance of zero
/// and an observation model term of zero.
#[derive(Debug)]
pub struct KalmanFilter {
    /// A reference utc from which the estimate is maintained.
    reference_utc: zx::Time,
    /// The monotonic time at which the estimate applies.
    monotonic: zx::Time,
    /// Element 0 of the state vector, i.e. estimated utc after reference_utc, in nanoseconds.
    estimate_0: f64,
    /// Element 1 of the state vector, i.e. estimated oscillator frequency as a factor.
    estimate_1: f64,
    /// Element 0,0 of the covariance matrix, i.e. utc estimate covariance in nanoseconds squared.
    /// Note 0,0 is the only non-zero element in the matrix.
    covariance_00: f64,
}

impl KalmanFilter {
    /// Construct a new KalmanFilter initialized to the supplied sample.
    pub fn new(sample: Sample) -> Self {
        let Sample { utc, monotonic, std_dev } = sample;
        let covariance_00 = duration_to_f64(std_dev).powf(2.0).max(MIN_COVARIANCE);
        KalmanFilter {
            reference_utc: utc,
            monotonic,
            estimate_0: 0f64,
            estimate_1: 1f64,
            covariance_00,
        }
    }

    /// Propagate the estimate forward to the requested monotonic time.
    fn predict(&mut self, monotonic: zx::Time) {
        let monotonic_step = duration_to_f64(monotonic - self.monotonic);
        self.monotonic = monotonic;
        // Estimated UTC increases by (change in monotonic time) * frequency.
        self.estimate_0 += self.estimate_1 * monotonic_step;
        // Estimated covariance increases as a function of the time step and oscillator error.
        self.covariance_00 += monotonic_step.powf(2.0) * *OSCILLATOR_ERROR_VARIANCE;
    }

    /// Correct the estimate by incorporating measurement data.
    fn correct(&mut self, utc: zx::Time, std_dev: zx::Duration) {
        let measurement_variance = duration_to_f64(std_dev).powf(2.0);
        let measurement_utc_offset = duration_to_f64(utc - self.reference_utc);
        // Gain is based on the relative variance of the apriori estimate and the new measurement...
        let k_0 = self.covariance_00 / (self.covariance_00 + measurement_variance);
        // ...and determines how much the measurement impacts the apriori estimate...
        self.estimate_0 += k_0 * (measurement_utc_offset - self.estimate_0);
        // ...and how much the covariance shrinks.
        self.covariance_00 = ((1f64 - k_0) * self.covariance_00).max(MIN_COVARIANCE);
    }

    /// Update the estimate to include the supplied sample.
    pub fn update(&mut self, Sample { utc, monotonic, std_dev }: Sample) -> Result<(), Error> {
        // Ignore any updates that are earlier than the current filter state. Samples from a single
        // time source should arrive in order due to the validation in time_source_manager, but its
        // not impossible that a backwards step occurs during a time source switch.
        if monotonic < self.monotonic {
            return Err(anyhow!(
                "sample monotonic={} prior to previous monotonic={}",
                monotonic.into_nanos(),
                self.monotonic.into_nanos()
            ));
        }

        // Calculate apriori by moving the estimate forward to the measurement's monotonic time.
        self.predict(monotonic);
        // Then correct to aposteriori by merging in the measurement.
        self.correct(utc, std_dev);
        Ok(())
    }

    /// Returns a `Transform` describing the estimated synthetic time and error as a function
    /// of the monotonic time.
    pub fn transform(&self) -> Transform {
        Transform {
            monotonic_offset: self.monotonic.into_nanos(),
            synthetic_offset: (self.reference_utc + f64_to_duration(self.estimate_0)).into_nanos(),
            // TODO(jsankey): Accommodate an oscillator frequency error when implementing the
            // frequency correction algorithm.
            rate_adjust_ppm: 0,
            error_bound_at_offset: ERROR_BOUND_FACTOR as u64 * self.covariance_00.sqrt() as u64,
            error_bound_growth_ppm: ERROR_BOUND_FACTOR * OSCILLATOR_ERROR_STD_DEV_PPM as u32,
        }
    }

    /// Returns the last updated monotonic to UTC offset.
    pub fn offset(&self) -> zx::Duration {
        self.reference_utc + f64_to_duration(self.estimate_0) - self.monotonic
    }

    /// Returns the square root of the last updated filter covariance.
    pub fn sqrt_covariance(&self) -> zx::Duration {
        f64_to_duration(self.covariance_00.sqrt())
    }
}

#[cfg(test)]
mod test {
    use {super::*, test_util::assert_near, zx::DurationNum};

    const TIME_1: zx::Time = zx::Time::from_nanos(10_000_000_000);
    const TIME_2: zx::Time = zx::Time::from_nanos(20_000_000_000);
    const OFFSET_1: zx::Duration = zx::Duration::from_seconds(777);
    const OFFSET_2: zx::Duration = zx::Duration::from_seconds(999);
    const STD_DEV_1: zx::Duration = zx::Duration::from_millis(22);
    const ZERO_DURATION: zx::Duration = zx::Duration::from_nanos(0);
    const SQRT_COV_1: u64 = STD_DEV_1.into_nanos() as u64;

    #[fuchsia::test]
    fn initialize() {
        let filter = KalmanFilter::new(Sample::new(TIME_1 + OFFSET_1, TIME_1, STD_DEV_1));
        let transform = filter.transform();
        assert_eq!(
            transform,
            Transform {
                monotonic_offset: TIME_1.into_nanos(),
                synthetic_offset: (TIME_1 + OFFSET_1).into_nanos(),
                rate_adjust_ppm: 0,
                error_bound_at_offset: 2 * SQRT_COV_1,
                error_bound_growth_ppm: 2 * OSCILLATOR_ERROR_STD_DEV_PPM as u32,
            }
        );
        assert_eq!(transform.synthetic(TIME_1), TIME_1 + OFFSET_1);
        assert_eq!(transform.synthetic(TIME_2), TIME_2 + OFFSET_1);
        assert_eq!(transform.error_bound(TIME_1), 2 * SQRT_COV_1);
        // Earlier time should return same error bound.
        assert_eq!(transform.error_bound(TIME_1 - 1.second()), 2 * SQRT_COV_1);
        // Later time should have a higher bound.
        assert_eq!(
            transform.error_bound(TIME_1 + 1.second()),
            2 * SQRT_COV_1 + 2000 * OSCILLATOR_ERROR_STD_DEV_PPM
        );
        assert_eq!(filter.offset(), OFFSET_1);
        assert_eq!(filter.sqrt_covariance(), STD_DEV_1);
    }

    #[fuchsia::test]
    fn kalman_filter_performance() {
        // Note: The expected outputs for these test inputs have been validated using the time
        // synchronization simulator we created during algorithm development.
        let mut filter = KalmanFilter::new(Sample::new(
            zx::Time::from_nanos(10001_000000000),
            zx::Time::from_nanos(1_000000000),
            zx::Duration::from_millis(50),
        ));
        assert_eq!(filter.reference_utc, zx::Time::from_nanos(10001_000000000));
        assert_near!(filter.estimate_0, 0f64, 1.0);
        assert_near!(filter.covariance_00, 2.5e15, 1.0);

        assert!(filter
            .update(Sample::new(
                zx::Time::from_nanos(10101_100000000),
                zx::Time::from_nanos(101_000000000),
                zx::Duration::from_millis(200),
            ))
            .is_ok());
        assert_near!(filter.estimate_0, 100_005887335.0, 1.0);
        assert_near!(filter.covariance_00, 2.3549341505449715e15, 1.0);

        assert!(filter
            .update(Sample::new(
                zx::Time::from_nanos(10300_900000000),
                zx::Time::from_nanos(301_000000000),
                zx::Duration::from_millis(100),
            ))
            .is_ok());
        assert_near!(filter.estimate_0, 299_985642106.0, 1.0);
        assert_near!(filter.covariance_00, 1.9119595120463945e15, 1.0);
    }

    #[fuchsia::test]
    fn covariance_minimum() {
        let mut filter = KalmanFilter::new(Sample::new(TIME_1 + OFFSET_1, TIME_1, ZERO_DURATION));
        assert_eq!(filter.covariance_00, MIN_COVARIANCE);
        assert!(filter.update(Sample::new(TIME_2 + OFFSET_2, TIME_2, ZERO_DURATION)).is_ok());
        assert_eq!(filter.covariance_00, MIN_COVARIANCE);
    }

    #[fuchsia::test]
    fn earlier_monotonic_ignored() {
        let mut filter = KalmanFilter::new(Sample::new(TIME_2 + OFFSET_1, TIME_2, STD_DEV_1));
        assert_near!(filter.estimate_0, 0.0, 1.0);
        assert!(filter.update(Sample::new(TIME_1 + OFFSET_1, TIME_1, STD_DEV_1)).is_err());
        assert_near!(filter.estimate_0, 0.0, 1.0);
    }
}
