// 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 crate::view::{NewViewParams, ViewAssistantPtr, ViewController, ViewControllerPtr, ViewKey};
use failure::{Error, ResultExt};
use fidl::endpoints::{RequestStream, ServerEnd, ServiceMarker};
use fidl_fuchsia_ui_app as viewsv2;
use fidl_fuchsia_ui_viewsv1::{
    ViewManagerMarker, ViewManagerProxy, ViewProviderMarker, ViewProviderRequest::CreateView,
    ViewProviderRequestStream,
};
use fidl_fuchsia_ui_viewsv1token::ViewOwnerMarker;
use fuchsia_app::{self as component, client::connect_to_service, server::FdioServer};
use fuchsia_async as fasync;
use fuchsia_scenic::SessionPtr;
use fuchsia_zircon::EventPair;
use futures::{TryFutureExt, TryStreamExt};
use lazy_static::lazy_static;
use parking_lot::Mutex;
use std::{any::Any, collections::BTreeMap, sync::Arc};

/// Trait that a mod author must implement. Currently responsible for creating
/// a view assistant when the Fuchsia view framework requests that the mod create
/// a view.
pub trait AppAssistant: Send {
    /// This method is responsible for setting up the AppAssistant implementation.
    /// _It's not clear if this is going to so useful, as anything that isn't
    /// initialized in the creation of the structure implementing AppAssistant
    /// is going to have to be represented as an `Option`, which is awkward._
    fn setup(&mut self) -> Result<(), Error>;

    /// Called when the Fuchsia view system requests that a view be created.
    fn create_view_assistant(&mut self, session: &SessionPtr) -> Result<ViewAssistantPtr, Error>;
}

pub type AppAssistantPtr = Mutex<Box<dyn AppAssistant>>;

/// Struct that implements module-wide responsibilties, currently limited
/// to creating views on request.
pub struct App {
    pub(crate) view_manager: ViewManagerProxy,
    view_controllers: BTreeMap<ViewKey, ViewControllerPtr>,
    next_key: ViewKey,
    assistant: Option<AppAssistantPtr>,
}

/// Reference to the singleton app. _This type is likely to change in the future so
/// using this type alias might make for easier forward migration._
pub type AppPtr = Arc<Mutex<App>>;

lazy_static! {
    /// Singleton reference to the running application
    pub static ref APP: AppPtr = App::new().expect("Failed to create app");
}

impl App {
    fn new() -> Result<AppPtr, Error> {
        let view_manager = connect_to_service::<ViewManagerMarker>()?;
        Ok(Arc::new(Mutex::new(App {
            view_manager,
            view_controllers: BTreeMap::new(),
            next_key: 0,
            assistant: None,
        })))
    }

    /// Starts an application based on Carnelian. The `assistant` parameter will
    /// be used to create new views when asked to do so by the Fuchsia view system.
    pub fn run(assistant: Box<AppAssistant>) -> Result<(), Error> {
        let mut executor = fasync::Executor::new().context("Error creating executor")?;

        APP.lock().set_assistant(Mutex::new(assistant));

        let fut = Self::start_services(&APP)?;

        APP.lock().assistant.as_ref().unwrap().lock().setup()?;

        executor.run_singlethreaded(fut)?;

        Ok(())
    }

    fn set_assistant(&mut self, assistant: AppAssistantPtr) {
        self.assistant = Some(assistant);
    }

    /// Method for app and view assistants to use from closures in
    /// order to reconnect with a specific `ViewController`.
    pub fn find_view_controller(&self, key: ViewKey) -> Option<&ViewControllerPtr> {
        self.view_controllers.get(&key)
    }

    /// Send a message to a specific view controller. Messages not handled by the ViewController
    /// will be forwarded to the `ViewControllerAssistant`.
    pub fn send_message(&mut self, target: ViewKey, msg: &Any) {
        if let Some(view) = self.view_controllers.get(&target) {
            view.lock().send_message(msg);
        }
    }

    pub(crate) fn create_view_assistant(
        &mut self, session: &SessionPtr,
    ) -> Result<ViewAssistantPtr, Error> {
        Ok(self
            .assistant
            .as_ref()
            .unwrap()
            .lock()
            .create_view_assistant(session)?)
    }

    fn create_view(&mut self, req: ServerEnd<ViewOwnerMarker>) -> Result<(), Error> {
        let view_controller = ViewController::new(self, NewViewParams::V1(req), self.next_key)?;
        self.view_controllers.insert(self.next_key, view_controller);
        self.next_key += 1;
        Ok(())
    }

    fn create_view2(&mut self, view_token: EventPair) -> Result<(), Error> {
        let view_controller =
            ViewController::new(self, NewViewParams::V2(view_token), self.next_key)?;
        self.view_controllers.insert(self.next_key, view_controller);
        self.next_key += 1;
        Ok(())
    }

    fn spawn_view_provider_server(chan: fasync::Channel, app: &AppPtr) {
        let app = app.clone();
        fasync::spawn(
            ViewProviderRequestStream::from_channel(chan)
                .try_for_each(move |req| {
                    let CreateView { view_owner, .. } = req;
                    app.lock()
                        .create_view(view_owner)
                        .unwrap_or_else(|e| eprintln!("create_view error: {:?}", e));
                    futures::future::ready(Ok(()))
                })
                .unwrap_or_else(|e| eprintln!("error running view_provider server: {:?}", e)),
        )
    }

    fn spawn_v2_view_provider_server(chan: fasync::Channel, app: &AppPtr) {
        let app = app.clone();
        fasync::spawn(
            viewsv2::ViewProviderRequestStream::from_channel(chan)
                .try_for_each(move |req| {
                    let viewsv2::ViewProviderRequest::CreateView { token, .. } = req;
                    app.lock()
                        .create_view2(token)
                        .unwrap_or_else(|e| eprintln!("create_view2 error: {:?}", e));
                    futures::future::ready(Ok(()))
                })
                .unwrap_or_else(|e| eprintln!("error running V2 view_provider server: {:?}", e)),
        )
    }

    fn start_services(app: &AppPtr) -> Result<FdioServer, Error> {
        let app_view_provider = app.clone();
        let app_view_provider2 = app.clone();
        let services_server = component::server::ServicesServer::new();
        let services_server = services_server
            .add_service((ViewProviderMarker::NAME, move |channel| {
                Self::spawn_view_provider_server(channel, &app_view_provider);
            }))
            .add_service((viewsv2::ViewProviderMarker::NAME, move |channel| {
                Self::spawn_v2_view_provider_server(channel, &app_view_provider2);
            }));
        Ok(services_server.start()?)
    }
}
