// 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.

//! AccountHandler manages the state of a single Fuchsia account and its personae on a Fuchsia
//! device, and provides access to authentication tokens for Service Provider accounts associated
//! with the Fuchsia account.

#![deny(missing_docs)]

mod account;
mod account_handler;
mod auth_provider_supplier;
mod common;
mod inspect;
mod lock_request;
mod persona;
mod pre_auth;
mod stored_account;

#[cfg(test)]
mod fake_account_handler_context;
#[cfg(test)]
mod fake_authenticator;
#[cfg(test)]
mod test_util;

use crate::account_handler::AccountHandler;
use crate::common::AccountLifetime;
use account_common::{AccountManagerError, LocalAccountId};
use anyhow::{Context as _, Error};
use fidl_fuchsia_identity_internal::AccountHandlerContextMarker;
use fuchsia_async as fasync;
use fuchsia_component::client::connect_to_service;
use fuchsia_component::server::ServiceFs;
use fuchsia_inspect::Inspector;
use futures::StreamExt;
use log::{error, info};
use std::sync::Arc;

type TokenManager = token_manager::TokenManager<auth_provider_supplier::AuthProviderSupplier>;

const DATA_DIR: &str = "/data";

/// This command line flag (prefixed with `--`) results in an in-memory ephemeral account.
const EPHEMERAL_FLAG: &str = "ephemeral";

/// This required command line option (prefixed with `--`), followed by a decimal string,
/// determines the local account identifier.
const ACCOUNT_ID_OPTION: &str = "account_id";

// TODO(dnordstrom): Remove all panics.
fn main() -> Result<(), Error> {
    let mut opts = getopts::Options::new();
    opts.optflag("", EPHEMERAL_FLAG, "this account is an in-memory ephemeral account");
    opts.reqopt("", ACCOUNT_ID_OPTION, "set the local account id", "ID");
    let args: Vec<String> = std::env::args().collect();
    let options = opts.parse(args)?;
    let lifetime = if options.opt_present(EPHEMERAL_FLAG) {
        AccountLifetime::Ephemeral
    } else {
        AccountLifetime::Persistent { account_dir: DATA_DIR.into() }
    };
    let account_id = {
        let account_id = options.opt_str(ACCOUNT_ID_OPTION).expect("Internal getopts error");
        LocalAccountId::from_canonical_str(&account_id).expect(&format!(
            "`{}` should be provided as an unsigned 64-bit integer (in decimal).",
            &account_id
        ))
    };

    fuchsia_syslog::init_with_tags(&[
        "auth",
        &format!("id<{}>", &account_id.to_canonical_string()),
    ])
    .expect("Can't init logger");
    info!("Starting account handler");

    let mut executor = fasync::Executor::new().context("Error creating executor")?;
    let inspector = Inspector::new();
    let mut fs = ServiceFs::new();
    inspector.serve(&mut fs)?;

    // TODO(dnordstrom): Find a testable way to inject global capabilities.
    let context = connect_to_service::<AccountHandlerContextMarker>()
        .expect("Error connecting to the AccountHandlerContext service");

    let pre_auth_manager = create_pre_auth_manager(&lifetime, &account_id)?;
    let account_handler =
        Arc::new(AccountHandler::new(context, account_id, lifetime, pre_auth_manager, &inspector));
    fs.dir("svc").add_fidl_service(move |stream| {
        let account_handler_clone = Arc::clone(&account_handler);
        fasync::Task::spawn(async move {
            account_handler_clone
                .handle_requests_from_stream(stream)
                .await
                .unwrap_or_else(|e| error!("Error handling AccountHandlerControl channel: {:?}", e))
        })
        .detach();
    });
    fs.take_and_serve_directory_handle()?;

    executor.run_singlethreaded(fs.collect::<()>());

    info!("Stopping account handler");
    Ok(())
}

/// Returns a pre-auth manager given the current lifetime and account id.
fn create_pre_auth_manager(
    lifetime: &AccountLifetime,
    id: &LocalAccountId,
) -> Result<Arc<dyn pre_auth::Manager>, AccountManagerError> {
    if lifetime == &AccountLifetime::Ephemeral {
        Ok(Arc::new(pre_auth::InMemoryManager::create(pre_auth::State::NoEnrollments)))
    } else {
        let store_name = format!("account_handler/{}", &id.to_canonical_string());
        Ok(Arc::new(pre_auth::StashManager::create(&store_name)?))
    }
}
