// 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 anyhow::{format_err, Context as _, Error};
use fidl_fuchsia_devicesettings::{
    DeviceSettingsManagerRequest, DeviceSettingsManagerRequestStream, DeviceSettingsWatcherProxy,
    Status, ValueType,
};
use fuchsia_async as fasync;
use fuchsia_component::server::{ServiceFs, ServiceFsDir};
use futures::{lock::Mutex, StreamExt, TryStreamExt};
use std::collections::HashMap;
use structopt::StructOpt;

#[derive(StructOpt, Debug)]
#[structopt(name = "mock_device_settings")]
/// Serves DeviceSettingsManager with a memory-backed database
struct Opt {
    #[structopt(short = "s")]
    /// Starts with a pre-set string key, format [k]=[v]
    /// e.g. DeviceName=my-device-name
    string_key: Vec<String>,
    #[structopt(short = "i")]
    /// Starts with a pre-set integer key, format [k]=[v]
    /// e.g. Audio=100
    int_key: Vec<String>,
}

#[derive(Debug)]
enum Key {
    StringKey(String),
    IntKey(i64),
}

struct DeviceSettingsManagerServer {
    keys: HashMap<String, Key>,
    watchers: HashMap<String, Vec<DeviceSettingsWatcherProxy>>,
}

impl DeviceSettingsManagerServer {
    fn run_watchers(&mut self, key: &str, t: ValueType) {
        if let Some(m) = self.watchers.get_mut(key) {
            m.retain(|w| {
                if let Err(e) = w.on_change_settings(t) {
                    if e.is_closed() {
                        return false;
                    }
                    log::info!("Error call watcher: {:?}", e);
                }
                return true;
            });
        }
    }
}

fn split_once(in_string: &str) -> Result<(&str, &str), Error> {
    let mut splitter = in_string.splitn(2, '=');
    let first = splitter.next().ok_or(format_err!("Invalid key value format"))?;
    let second = splitter.next().ok_or(format_err!("Invalid key value format"))?;
    Ok((first, second))
}

fn config_state(state: &mut DeviceSettingsManagerServer, opt: Opt) -> Result<(), Error> {
    for s_key in opt.string_key {
        let (k, v) = split_once(&s_key)?;
        log::info!("Startup {}={}", k, v);
        if let Some(previous_value) =
            state.keys.insert(String::from(k), Key::StringKey(String::from(v)))
        {
            panic!("duplicate key {}={} in startup, previously set to {:?}", k, v, previous_value);
        }
    }

    for i_key in opt.int_key {
        let (k, v) = split_once(&i_key)?;
        let v = v.parse::<i64>()?;
        log::info!("Startup {}={}", k, v);
        if let Some(previous_value) = state.keys.insert(String::from(k), Key::IntKey(v)) {
            panic!("duplicate key {}={} in startup, previously set to {:?}", k, v, previous_value);
        }
    }

    Ok(())
}

async fn run_request_stream(
    state: &Mutex<DeviceSettingsManagerServer>,
    stream: DeviceSettingsManagerRequestStream,
) {
    stream
        .try_for_each(move |req| async move {
            let mut state = state.lock().await;
            match req {
                DeviceSettingsManagerRequest::GetInteger { key, responder } => {
                    match state.keys.get(&key) {
                        None => {
                            log::info!("Key {} doesn't exist", key);
                            responder.send(0, Status::ErrNotSet)
                        }
                        Some(Key::IntKey(val)) => responder.send(*val, Status::Ok),
                        _ => {
                            log::info!("Key {} is not an integer", key);
                            responder.send(0, Status::ErrIncorrectType)
                        }
                    }
                }
                DeviceSettingsManagerRequest::GetString { key, responder } => {
                    match state.keys.get(&key) {
                        None => {
                            log::info!("Key {} doesn't exist", key);
                            responder.send("", Status::ErrNotSet)
                        }
                        Some(Key::StringKey(val)) => responder.send(val, Status::Ok),
                        _ => {
                            log::info!("Key {} is not a string", key);
                            responder.send("", Status::ErrIncorrectType)
                        }
                    }
                }
                DeviceSettingsManagerRequest::SetInteger { key, val, responder } => {
                    match state.keys.get(&key) {
                        Some(Key::IntKey(_)) => {
                            log::info!("Set {}={}", key, val);
                            state.run_watchers(&key, ValueType::Number);
                            let _: Option<Key> = state.keys.insert(key, Key::IntKey(val));
                            responder.send(true)
                        }
                        _ => {
                            log::info!("Failed to set integer key {}={}", key, val);
                            responder.send(false)
                        }
                    }
                }
                DeviceSettingsManagerRequest::SetString { key, val, responder } => {
                    match state.keys.get(&key) {
                        Some(Key::StringKey(_)) => {
                            log::info!("Set {}={}", key, val);
                            state.run_watchers(&key, ValueType::Text);
                            let _: Option<Key> = state.keys.insert(key, Key::StringKey(val));
                            responder.send(true)
                        }
                        _ => {
                            log::info!("Failed to set string key {}={}", key, val);
                            responder.send(false)
                        }
                    }
                }
                DeviceSettingsManagerRequest::Watch { key, watcher, responder } => {
                    match state.keys.get(&key) {
                        None => {
                            log::info!("Can't watch key {}, it doesn't exist", key);
                            responder.send(Status::ErrInvalidSetting)
                        }
                        _ => match watcher.into_proxy() {
                            Ok(watcher) => {
                                let mv = state.watchers.entry(key).or_insert(Vec::new());
                                mv.push(watcher);
                                responder.send(Status::Ok)
                            }
                            Err(e) => {
                                log::info!("Error watching key {}: {}", key, e);
                                responder.send(Status::ErrUnknown)
                            }
                        },
                    }
                }
            }
        })
        .await
        .unwrap_or_else(|e| {
            log::error!("error running mock device settings server: {:?}", e);
        })
}

#[fasync::run_singlethreaded]
async fn main() -> Result<(), Error> {
    let () = fuchsia_syslog::init().context("cannot init logger")?;

    let opt = Opt::from_args();
    let mut state = DeviceSettingsManagerServer { keys: HashMap::new(), watchers: HashMap::new() };
    let () = config_state(&mut state, opt)?;
    let state = Mutex::new(state);
    let mut fs = ServiceFs::new();
    let _: &mut ServiceFsDir<'_, _> =
        fs.dir("svc").add_fidl_service(|stream: DeviceSettingsManagerRequestStream| stream);
    let _: &mut ServiceFs<_> = fs.take_and_serve_directory_handle()?;
    let () = fs.for_each_concurrent(None, |stream| run_request_stream(&state, stream)).await;
    Ok(())
}

#[cfg(test)]
mod test {
    use anyhow::Context as _;
    use fidl_fuchsia_devicesettings::{
        DeviceSettingsManagerMarker, DeviceSettingsWatcherMarker, DeviceSettingsWatcherRequest,
        Status,
    };
    use fuchsia_async as fasync;
    use fuchsia_component::client;
    use futures::{future, TryStreamExt};

    #[fasync::run_singlethreaded]
    #[test]
    async fn test_string_key() {
        let manager = client::connect_to_service::<DeviceSettingsManagerMarker>().unwrap();
        let res = manager
            .set_string("StringKey", "HelloWorld")
            .await
            .context("can't set string")
            .unwrap();
        assert_eq!(res, true);
        let (val, status) =
            manager.get_string("StringKey").await.context("can't get string").unwrap();
        assert_eq!(status, Status::Ok);
        assert_eq!(val, "HelloWorld");
    }

    #[fasync::run_singlethreaded]
    #[test]
    async fn test_int_key() {
        let manager = client::connect_to_service::<DeviceSettingsManagerMarker>().unwrap();
        let res = manager.set_integer("IntKey", 1234).await.context("can't set int").unwrap();
        assert_eq!(res, true);
        let (val, status) = manager.get_integer("IntKey").await.context("can't get int").unwrap();
        assert_eq!(status, Status::Ok);
        assert_eq!(val, 1234);
    }

    #[fasync::run_singlethreaded]
    #[test]
    async fn test_watch_key() {
        let manager = client::connect_to_service::<DeviceSettingsManagerMarker>().unwrap();
        let (watcher_client_end, watcher_server_end) =
            fidl::endpoints::create_endpoints::<DeviceSettingsWatcherMarker>().unwrap();
        let status =
            manager.watch("WatchKey", watcher_client_end).await.context("can't set watch").unwrap();
        assert_eq!(status, Status::Ok);

        let res = manager.set_integer("WatchKey", 3456).await.context("can't set int").unwrap();
        assert_eq!(res, true);

        let (val, status) = manager.get_integer("WatchKey").await.context("can't get int").unwrap();
        assert_eq!(status, Status::Ok);
        assert_eq!(val, 3456);

        let mut wait_watch = watcher_server_end
            .into_stream()
            .context("Can't take request stream")
            .unwrap()
            .try_filter_map(|req| match req {
                DeviceSettingsWatcherRequest::OnChangeSettings { type_: _, control_handle: _ } => {
                    future::ok(Some(()))
                }
            });

        let () = wait_watch
            .try_next()
            .await
            .expect("failed to watch")
            .expect("stream ended unexpectedly");
    }
}
