// Copyright 2019 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 {
    failure::Fail,
    fuchsia_syslog::{fx_log_err, fx_log_info},
    fuchsia_url::pkg_url::PkgUrl,
    fuchsia_zircon::Duration,
    serde_derive::Deserialize,
    std::{cmp, fs::File, io::Read, num::NonZeroU64},
};

/// Static service configuration options.
#[derive(Debug, Default, PartialEq, Eq)]
pub struct Config {
    poll_frequency: Option<Duration>,
    update_package_url: Option<PkgUrl>,
}

impl Config {
    pub fn poll_frequency(&self) -> Option<Duration> {
        self.poll_frequency
    }

    pub fn update_package_url(&self) -> Option<&PkgUrl> {
        self.update_package_url.as_ref()
    }

    pub fn load_from_config_data_or_default() -> Config {
        let f = match File::open("/config/data/ota_config.json") {
            Ok(f) => f,
            Err(e) => {
                fx_log_info!("no config found, using defaults: {:?}", e.kind());
                return Config::default();
            }
        };

        Self::load(f).unwrap_or_else(|e| {
            fx_log_err!("unable to load config, using defaults: {:?}", e);
            Config::default()
        })
    }

    fn load(r: impl Read) -> Result<Config, ConfigLoadError> {
        #[derive(Debug, Deserialize)]
        #[serde(deny_unknown_fields)]
        struct ParseConfig {
            poll_frequency_minutes: Option<NonZeroU64>,
            update_package_url: Option<PkgUrl>,
        }

        let config =
            serde_json::from_reader::<_, ParseConfig>(r).map_err(ConfigLoadError::Parse)?;
        if config.update_package_url.as_ref().map(|url| url.resource().is_some()).unwrap_or(false) {
            return Err(ConfigLoadError::UpdatePackageUrlContainsResource);
        }

        Ok(Config {
            poll_frequency: config.poll_frequency_minutes.map(|freq| {
                // zx::Duration will wrap on overflow when converting to nanoseconds. Ensure a
                // config file cannot specify a negative duration by clamping to the maximum number
                // of minutes that can be represented as nanoseconds in an i64.
                let max_minutes_duration =
                    Duration::from_nanos(std::i64::MAX).into_minutes() as u64;
                Duration::from_minutes(cmp::min(freq.get(), max_minutes_duration) as i64)
            }),
            update_package_url: config.update_package_url,
        })
    }
}

#[derive(Debug, Fail)]
enum ConfigLoadError {
    #[fail(display = "parse error: {}", _0)]
    Parse(#[cause] serde_json::Error),

    #[fail(display = "update_package_url must not contain a resource path")]
    UpdatePackageUrlContainsResource,
}

#[cfg(test)]
#[derive(Debug)]
pub struct ConfigBuilder(Config);

#[cfg(test)]
impl ConfigBuilder {
    pub fn new() -> Self {
        Self(Config::default())
    }

    pub fn poll_frequency(mut self, duration: impl Into<Duration>) -> Self {
        self.0.poll_frequency = Some(duration.into());
        self
    }

    pub fn build(self) -> Config {
        self.0
    }
}

#[cfg(test)]
mod tests {
    use {super::*, matches::assert_matches, serde_json::json};

    fn verify_load(input: serde_json::Value, expected: Config) {
        let input = input.to_string();

        assert_eq!(Config::load(input.as_bytes()).unwrap(), expected);
    }

    #[test]
    fn test_load() {
        verify_load(
            json!({
                "update_package_url": "fuchsia-pkg://fuchsia.com/abc",
                "poll_frequency_minutes": 123,
            }),
            Config {
                poll_frequency: Some(Duration::from_minutes(123)),
                update_package_url: Some(PkgUrl::parse("fuchsia-pkg://fuchsia.com/abc").unwrap()),
            },
        );
    }

    #[test]
    fn test_missing_fields_are_defaults() {
        verify_load(
            json!({
                "update_package_url": "fuchsia-pkg://fuchsia.com/the-update",
            }),
            Config {
                poll_frequency: None,
                update_package_url: Some(
                    PkgUrl::parse("fuchsia-pkg://fuchsia.com/the-update").unwrap(),
                ),
            },
        );
        verify_load(
            json!({
                "poll_frequency_minutes": 1,
            }),
            Config { poll_frequency: Some(Duration::from_minutes(1)), update_package_url: None },
        );
    }

    #[test]
    fn test_no_config_data_is_default() {
        assert_eq!(Config::load_from_config_data_or_default(), Config::default());
    }

    #[test]
    fn test_load_empty_is_default() {
        assert_matches!(
            Config::load("{}".as_bytes()),
            Ok(ref config) if config == &Config::default());
    }

    #[test]
    fn test_load_rejects_invalid() {
        assert_matches!(
            Config::load("not json".as_bytes()),
            Err(ConfigLoadError::Parse(ref err)) if err.is_syntax());
    }

    #[test]
    fn test_load_rejects_resource_path() {
        let input = json!({
            "update_package_url": "fuchsia-pkg://fuchsia.com/update/0#unexpected/resource.path",
        })
        .to_string();

        assert_matches!(
            Config::load(input.as_bytes()),
            Err(ConfigLoadError::UpdatePackageUrlContainsResource)
        );
    }

    #[test]
    fn test_load_rejects_zero_poll_frequency() {
        let input = json!({
            "poll_frequency_minutes": 0,
        })
        .to_string();

        assert_matches!(
            Config::load(input.as_bytes()),
            Err(ConfigLoadError::Parse(ref err)) if err.is_data());
    }

    #[test]
    fn test_load_clamps_large_poll_frequency() {
        let max_duration = Duration::from_nanos(std::i64::MAX);
        let max_duration_minutes = max_duration.into_minutes();

        let verify_clamp = |minutes| {
            verify_load(
                json!({
                    "poll_frequency_minutes": minutes,
                }),
                Config {
                    poll_frequency: Some(Duration::from_minutes(max_duration_minutes)),
                    update_package_url: None,
                },
            );
        };

        verify_clamp(max_duration_minutes as u64);
        verify_clamp(max_duration_minutes as u64 + 1);
        verify_clamp(std::i64::MAX as u64);
        verify_clamp(std::u64::MAX);
    }
}
