// Copyright 2018 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 account_common::{AccountManagerError, LocalAccountId};
use failure::{format_err, ResultExt};
use fidl::endpoints::ClientEnd;
use fidl_fuchsia_auth_account::Status;
use fidl_fuchsia_auth_account_internal::{AccountHandlerControlMarker, AccountHandlerControlProxy};
use fuchsia_app::client::{App, Launcher};
use fuchsia_zircon as zx;
use futures::prelude::*;
use log::{info, warn};

/// The information necessary to maintain a connection to an AccountHandler component instance.
pub struct AccountHandlerConnection {
    /// An `App` object for the launched AccountHandler.
    ///
    /// Note: This must remain in scope for the component to remain running, but never needs to be
    /// read.
    _app: App,

    /// A `Proxy` connected to the AccountHandlerControl interface on the launched AccountHandler.
    proxy: AccountHandlerControlProxy,
}

/// The url used to launch new AccountHandler component instances.
const ACCOUNT_HANDLER_URL: &str =
    "fuchsia-pkg://fuchsia.com/account_handler#meta/account_handler.cmx";

impl AccountHandlerConnection {
    /// Launches a new AccountHandler component instance and establishes a connection to its
    /// control channel.
    pub fn new() -> Result<Self, AccountManagerError> {
        info!("Launching new AccountHandler instance");

        let launcher = Launcher::new()
            .context("Failed to start launcher")
            .map_err(|err| AccountManagerError::new(Status::IoError).with_cause(err))?;
        let app = launcher
            .launch(ACCOUNT_HANDLER_URL.to_string(), None)
            .context("Failed to launch AccountHandler")
            .map_err(|err| AccountManagerError::new(Status::IoError).with_cause(err))?;
        let proxy = app
            .connect_to_service(AccountHandlerControlMarker)
            .context("Failed to connect to AccountHandlerControl")
            .map_err(|err| AccountManagerError::new(Status::InternalError).with_cause(err))?;
        Ok(AccountHandlerConnection { _app: app, proxy })
    }

    /// Launches a new AccountHandler component instance, establishes a connection to its control
    /// channel, and requests that it loads an existing account.
    pub async fn new_for_account(account_id: &LocalAccountId) -> Result<Self, AccountManagerError> {
        let connection = Self::new()?;
        let mut fidl_account_id = account_id.clone().into();
        // TODO(jsankey): Supply a real AccountHandlerContext
        let (_, dummy_context) = zx::Channel::create()
            .context("Failed to create AccountHandlerContext channel")
            .map_err(|err| AccountManagerError::new(Status::IoError).with_cause(err))?;
        match await!(connection
            .proxy
            .load_account(ClientEnd::new(dummy_context), &mut fidl_account_id))
        .map_err(|err| AccountManagerError::new(Status::IoError).with_cause(err))?
        {
            Status::Ok => Ok(connection),
            stat => Err(AccountManagerError::new(stat)
                .with_cause(format_err!("Error loading existing account"))),
        }
    }

    /// Returns the AccountHandlerControlProxy for this connection
    pub fn proxy(&self) -> &AccountHandlerControlProxy {
        &self.proxy
    }

    /// Requests that the AccountHandler component instance terminate gracefully.
    ///
    /// Any subsequent operations that attempt to use `proxy()` will fail after this call. The
    /// resources associated with the connection when only be freed once the
    /// `AccountHandlerConnection` is dropped.
    pub async fn terminate(&self) {
        let mut event_stream = self.proxy.take_event_stream();
        if let Err(err) = self.proxy.terminate() {
            warn!("Error gracefully terminating account handler {:?}", err);
        } else {
            while let Ok(Some(_)) = await!(event_stream.try_next()) {}
            info!("Gracefully terminated AccountHandler instance");
        }
    }
}
