// 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 crate::channel::ChannelConfigs;
use anyhow::{anyhow, Error};
use fidl_fuchsia_boot::{ArgumentsMarker, ArgumentsProxy};
use log::{error, info, warn};
use omaha_client::{
    common::{App, AppSet, UserCounting, Version},
    configuration::{Config, Updater},
    protocol::{request::OS, Cohort},
};
use std::fs;
use std::io;

#[cfg(not(test))]
use sysconfig_client::channel::read_channel_config;

#[cfg(test)]
use sysconfig_mock::read_channel_config;

/// The source of the channel configuration.
#[derive(Debug, Eq, PartialEq)]
pub enum ChannelSource {
    MinFS,
    SysConfig,
    Default,
    VbMeta,
}

pub async fn get_app_set(
    version: &str,
    channel_configs: &Option<ChannelConfigs>,
) -> (AppSet, ChannelSource) {
    let (appid, mut channel) = get_appid_and_channel_from_vbmeta().await.unwrap_or_else(|e| {
        warn!("Failed to get app id and channel from vbmeta {:?}", e);
        (None, None)
    });
    let channel_source = if channel.is_some() {
        ChannelSource::VbMeta
    } else {
        let sysconfig_channel_config = read_channel_config();
        info!("Channel configuration in sysconfig: {:?}", sysconfig_channel_config);
        channel = sysconfig_channel_config.map(|config| config.channel_name().to_string()).ok();
        if channel.is_some() {
            ChannelSource::SysConfig
        } else {
            channel = channel_configs.as_ref().and_then(|configs| configs.default_channel.clone());
            if channel.is_some() {
                ChannelSource::Default
            } else {
                // Channel will be loaded from `Storage` by state machine.
                ChannelSource::MinFS
            }
        }
    };
    // If no appid in vbmeta, look up the appid of the channel from channel configs.
    let appid = appid.or_else(|| {
        channel_configs.as_ref().and_then(|configs| {
            channel.as_ref().and_then(|channel| {
                configs
                    .known_channels
                    .iter()
                    .find(|c| &c.name == channel)
                    .and_then(|c| c.appid.clone())
            })
        })
    });
    let id = appid.unwrap_or_else(|| match fs::read_to_string("/config/data/omaha_app_id") {
        Ok(id) => id,
        Err(e) => {
            error!("Unable to read omaha app id from config/data: {:?}", e);
            String::new()
        }
    });
    let version = match version.parse::<Version>() {
        Ok(version) => version,
        Err(e) => {
            error!("Unable to parse '{}' as Omaha version format: {:?}", version, e);
            Version::from([0])
        }
    };
    let cohort = Cohort { hint: channel.clone(), name: channel, ..Cohort::default() };
    (
        // Fuchsia only has a single app.
        AppSet::new(vec![App {
            id,
            version,
            fingerprint: None,
            cohort,
            user_counting: UserCounting::ClientRegulatedByDate(None),
        }]),
        channel_source,
    )
}

pub async fn get_config(version: &str) -> Config {
    // This file does not exist in production, it is only used in integration/e2e testing.
    let service_url = match get_service_url_from_vbmeta().await {
        Ok(Some(url)) => url,
        _ => fs::read_to_string("/config/data/omaha_url")
            .unwrap_or("https://clients2.google.com/service/update2/fuchsia/json".to_string()),
    };
    Config {
        updater: Updater { name: "Fuchsia".to_string(), version: Version::from([0, 0, 1, 0]) },

        os: OS {
            platform: "Fuchsia".to_string(),
            version: version.to_string(),
            service_pack: "".to_string(),
            arch: std::env::consts::ARCH.to_string(),
        },

        service_url,
    }
}

pub fn get_version() -> Result<String, io::Error> {
    fs::read_to_string("/config/build-info/version").map(|s| s.trim_end().to_string())
}

async fn get_appid_and_channel_from_vbmeta() -> Result<(Option<String>, Option<String>), Error> {
    let proxy = fuchsia_component::client::connect_to_service::<ArgumentsMarker>()?;
    get_appid_and_channel_from_vbmeta_impl(proxy).await
}

async fn get_appid_and_channel_from_vbmeta_impl(
    proxy: ArgumentsProxy,
) -> Result<(Option<String>, Option<String>), Error> {
    let vec = vec!["omaha_app_id", "ota_channel"];
    let res = proxy.get_strings(&mut vec.into_iter()).await?;
    if res.len() != 2 {
        Err(anyhow!("Remote endpoint returned {} values, expected 2", res.len()))
    } else {
        Ok((res[0].clone(), res[1].clone()))
    }
}

async fn get_service_url_from_vbmeta() -> Result<Option<String>, Error> {
    let proxy = fuchsia_component::client::connect_to_service::<ArgumentsMarker>()?;
    get_service_url_from_vbmeta_impl(proxy).await
}

async fn get_service_url_from_vbmeta_impl(proxy: ArgumentsProxy) -> Result<Option<String>, Error> {
    Ok(proxy.get_string("omaha_url").await?)
}

#[cfg(test)]
mod sysconfig_mock {
    use std::cell::RefCell;
    use sysconfig_client::channel::{ChannelConfigError, OtaUpdateChannelConfig};

    thread_local! {
        static MOCK_RESULT: RefCell<Result<OtaUpdateChannelConfig, ChannelConfigError>> =
            RefCell::new(Err(ChannelConfigError::Magic(0)));
    }

    pub(super) fn read_channel_config() -> Result<OtaUpdateChannelConfig, ChannelConfigError> {
        MOCK_RESULT.with(|result| result.replace(Err(ChannelConfigError::Magic(0))))
    }

    pub(super) fn set_read_channel_config_result(
        new_result: Result<OtaUpdateChannelConfig, ChannelConfigError>,
    ) {
        MOCK_RESULT.with(|result| *result.borrow_mut() = new_result);
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::channel::ChannelConfig;
    use fidl::endpoints::create_proxy_and_stream;
    use fidl_fuchsia_boot::ArgumentsRequest;
    use fuchsia_async as fasync;
    use futures::prelude::*;
    use sysconfig_client::channel::OtaUpdateChannelConfig;

    #[fasync::run_singlethreaded(test)]
    async fn test_get_config() {
        let config = get_config("1.2.3.4").await;
        assert_eq!(config.updater.name, "Fuchsia");
        let os = config.os;
        assert_eq!(os.platform, "Fuchsia");
        assert_eq!(os.version, "1.2.3.4");
        assert_eq!(os.arch, std::env::consts::ARCH);
        assert_eq!(config.service_url, "https://clients2.google.com/service/update2/fuchsia/json");
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_app_set() {
        let (app_set, channel_source) = get_app_set("1.2.3.4", &None).await;
        assert_eq!(channel_source, ChannelSource::MinFS);
        let apps = app_set.to_vec().await;
        assert_eq!(apps.len(), 1);
        assert_eq!(apps[0].id, "fuchsia:test-app-id");
        assert_eq!(apps[0].version, Version::from([1, 2, 3, 4]));
        assert_eq!(apps[0].cohort.name, None);
        assert_eq!(apps[0].cohort.hint, None);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_app_set_default_channel() {
        let (app_set, channel_source) = get_app_set(
            "1.2.3.4",
            &Some(ChannelConfigs {
                default_channel: Some("default-channel".to_string()),
                known_channels: vec![],
            }),
        )
        .await;
        assert_eq!(channel_source, ChannelSource::Default);
        let apps = app_set.to_vec().await;
        assert_eq!(apps.len(), 1);
        assert_eq!(apps[0].id, "fuchsia:test-app-id");
        assert_eq!(apps[0].version, Version::from([1, 2, 3, 4]));
        assert_eq!(apps[0].cohort.name, Some("default-channel".to_string()));
        assert_eq!(apps[0].cohort.hint, Some("default-channel".to_string()));
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_app_set_appid_from_channel_configs() {
        let (app_set, channel_source) = get_app_set(
            "1.2.3.4",
            &Some(ChannelConfigs {
                default_channel: Some("some-channel".to_string()),
                known_channels: vec![
                    ChannelConfig::new("no-appid-channel"),
                    ChannelConfig::with_appid("wrong-channel", "wrong-appid"),
                    ChannelConfig::with_appid("some-channel", "some-appid"),
                    ChannelConfig::with_appid("some-other-channel", "some-other-appid"),
                ],
            }),
        )
        .await;
        assert_eq!(channel_source, ChannelSource::Default);
        let apps = app_set.to_vec().await;
        assert_eq!(apps.len(), 1);
        assert_eq!(apps[0].id, "some-appid");
        assert_eq!(apps[0].version, Version::from([1, 2, 3, 4]));
        assert_eq!(apps[0].cohort.name, Some("some-channel".to_string()));
        assert_eq!(apps[0].cohort.hint, Some("some-channel".to_string()));
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_app_set_appid_from_channel_configs_sysconfig() {
        sysconfig_mock::set_read_channel_config_result(OtaUpdateChannelConfig::new(
            "some-channel",
            "some-repo",
        ));
        let (app_set, channel_source) = get_app_set(
            "1.2.3.4",
            &Some(ChannelConfigs {
                default_channel: Some("some-other-channel".to_string()),
                known_channels: vec![
                    ChannelConfig::new("no-appid-channel"),
                    ChannelConfig::with_appid("wrong-channel", "wrong-appid"),
                    ChannelConfig::with_appid("some-channel", "some-appid"),
                    ChannelConfig::with_appid("some-other-channel", "some-other-appid"),
                ],
            }),
        )
        .await;
        assert_eq!(channel_source, ChannelSource::SysConfig);
        let apps = app_set.to_vec().await;
        assert_eq!(apps.len(), 1);
        assert_eq!(apps[0].id, "some-appid");
        assert_eq!(apps[0].version, Version::from([1, 2, 3, 4]));
        assert_eq!(apps[0].cohort.name, Some("some-channel".to_string()));
        assert_eq!(apps[0].cohort.hint, Some("some-channel".to_string()));
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_app_set_invalid_version() {
        let (app_set, _) = get_app_set("invalid version", &None).await;
        let apps = app_set.to_vec().await;
        assert_eq!(apps[0].version, Version::from([0]));
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_appid_and_channel_from_vbmeta() {
        let (proxy, mut stream) = create_proxy_and_stream::<ArgumentsMarker>().unwrap();
        let fut = async move {
            let (appid, channel) = get_appid_and_channel_from_vbmeta_impl(proxy).await.unwrap();
            assert_eq!(appid, Some("test-appid".to_string()));
            assert_eq!(channel, Some("test-channel".to_string()));
        };
        let stream_fut = async move {
            match stream.next().await.unwrap() {
                Ok(ArgumentsRequest::GetStrings { keys, responder }) => {
                    assert_eq!(keys, vec!["omaha_app_id", "ota_channel"]);
                    let vec: Vec<Option<&str>> = vec![Some("test-appid"), Some("test-channel")];
                    responder.send(&mut vec.into_iter()).expect("send failed");
                }
                request => panic!("Unexpected request: {:?}", request),
            }
        };
        future::join(fut, stream_fut).await;
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_appid_and_channel_from_vbmeta_missing() {
        let (proxy, mut stream) = create_proxy_and_stream::<ArgumentsMarker>().unwrap();
        let fut = async move {
            let (appid, channel) = get_appid_and_channel_from_vbmeta_impl(proxy).await.unwrap();
            assert_eq!(appid, None);
            assert_eq!(channel, None);
        };
        let stream_fut = async move {
            match stream.next().await.unwrap() {
                Ok(ArgumentsRequest::GetStrings { keys, responder }) => {
                    assert_eq!(keys.len(), 2);
                    let ret: Vec<Option<&str>> = vec![None, None];
                    responder.send(&mut ret.into_iter()).expect("send failed");
                }
                request => panic!("Unexpected request: {:?}", request),
            }
        };
        future::join(fut, stream_fut).await;
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_appid_and_channel_from_vbmeta_error() {
        let (proxy, mut stream) = create_proxy_and_stream::<ArgumentsMarker>().unwrap();
        let fut = async move {
            assert!(get_appid_and_channel_from_vbmeta_impl(proxy).await.is_err());
        };
        let stream_fut = async move {
            match stream.next().await.unwrap() {
                Ok(ArgumentsRequest::GetStrings { .. }) => {
                    // Don't respond.
                }
                request => panic!("Unexpected request: {:?}", request),
            }
        };
        future::join(fut, stream_fut).await;
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_service_url_from_vbmeta() {
        let (proxy, mut stream) = create_proxy_and_stream::<ArgumentsMarker>().unwrap();
        let fut = async move {
            let url = get_service_url_from_vbmeta_impl(proxy).await.unwrap();
            assert_eq!(url, Some("test-url".to_string()));
        };
        let stream_fut = async move {
            match stream.next().await.unwrap() {
                Ok(ArgumentsRequest::GetString { key, responder }) => {
                    assert_eq!(key, "omaha_url");
                    responder.send(Some("test-url")).expect("send failed");
                }
                request => panic!("Unexpected request: {:?}", request),
            }
        };
        future::join(fut, stream_fut).await;
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_service_url_from_vbmeta_missing() {
        let (proxy, mut stream) = create_proxy_and_stream::<ArgumentsMarker>().unwrap();
        let fut = async move {
            let url = get_service_url_from_vbmeta_impl(proxy).await.unwrap();
            assert_eq!(url, None);
        };
        let stream_fut = async move {
            match stream.next().await.unwrap() {
                Ok(ArgumentsRequest::GetString { key, responder }) => {
                    assert_eq!(key, "omaha_url");
                    responder.send(None).expect("send failed");
                }
                request => panic!("Unexpected request: {:?}", request),
            }
        };
        future::join(fut, stream_fut).await;
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_service_url_from_vbmeta_error() {
        let (proxy, mut stream) = create_proxy_and_stream::<ArgumentsMarker>().unwrap();
        let fut = async move {
            assert!(get_service_url_from_vbmeta_impl(proxy).await.is_err());
        };
        let stream_fut = async move {
            match stream.next().await.unwrap() {
                Ok(ArgumentsRequest::GetString { .. }) => {
                    // Don't respond.
                }
                request => panic!("Unexpected request: {:?}", request),
            }
        };
        future::join(fut, stream_fut).await;
    }
}
