// 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::Error, async_trait::async_trait, clonable_error::ClonableError,
    fidl::endpoints::ServerEnd, fidl_fuchsia_component as fcomponent,
    fidl_fuchsia_component_runner as fcrunner, fuchsia_async as fasync, fuchsia_zircon as zx,
    futures::stream::TryStreamExt, thiserror::Error,
};

/// Executes a component instance.
/// TODO: The runner should return a trait object to allow the component instance to be stopped,
/// binding to services, and observing abnormal termination.  In other words, a wrapper that
/// encapsulates fcrunner::ComponentController FIDL interfacing concerns.
/// TODO: Consider defining an internal representation for `fcrunner::ComponentStartInfo` so as to
/// further isolate the `Model` from FIDL interfacting concerns.
#[async_trait]
pub trait Runner: Sync + Send {
    #[must_use]
    async fn start(
        &self,
        start_info: fcrunner::ComponentStartInfo,
        server_end: ServerEnd<fcrunner::ComponentControllerMarker>,
    );
}

/// Errors produced by `Runner`.
#[derive(Debug, Error, Clone)]
pub enum RunnerError {
    #[error("invalid arguments provided for component with url \"{}\": {}", url, err)]
    InvalidArgs {
        url: String,
        #[source]
        err: ClonableError,
    },
    #[error("unable to load component with url \"{}\": {}", url, err)]
    ComponentLoadError {
        url: String,
        #[source]
        err: ClonableError,
    },
    #[error("runner failed to launch component with url \"{}\": {}", url, err)]
    ComponentLaunchError {
        url: String,
        #[source]
        err: ClonableError,
    },
    #[error("failed to populate the runtime directory: {}", err)]
    ComponentRuntimeDirectoryError {
        #[source]
        err: ClonableError,
    },
    #[error("failed to connect to the runner: {}", err)]
    RunnerConnectionError {
        #[source]
        err: ClonableError,
    },
    #[error("remote runners unsupported")]
    Unsupported,
}

impl RunnerError {
    pub fn invalid_args(url: impl Into<String>, err: impl Into<Error>) -> RunnerError {
        RunnerError::InvalidArgs { url: url.into(), err: err.into().into() }
    }

    pub fn component_load_error(url: impl Into<String>, err: impl Into<Error>) -> RunnerError {
        RunnerError::ComponentLoadError { url: url.into(), err: err.into().into() }
    }

    pub fn component_launch_error(url: impl Into<String>, err: impl Into<Error>) -> RunnerError {
        RunnerError::ComponentLaunchError { url: url.into(), err: err.into().into() }
    }

    pub fn component_runtime_directory_error(err: impl Into<Error>) -> RunnerError {
        RunnerError::ComponentRuntimeDirectoryError { err: err.into().into() }
    }

    pub fn runner_connection_error(err: impl Into<Error>) -> RunnerError {
        RunnerError::RunnerConnectionError { err: err.into().into() }
    }

    /// Convert this error into its approximate `fuchsia.component.Error` equivalent.
    pub fn as_fidl_error(&self) -> fcomponent::Error {
        match self {
            RunnerError::InvalidArgs { .. } => fcomponent::Error::InvalidArguments,
            RunnerError::ComponentLoadError { .. } => fcomponent::Error::InstanceCannotStart,
            RunnerError::ComponentLaunchError { .. } => fcomponent::Error::InstanceCannotStart,
            RunnerError::ComponentRuntimeDirectoryError { .. } => fcomponent::Error::Internal,
            RunnerError::RunnerConnectionError { .. } => fcomponent::Error::Internal,
            RunnerError::Unsupported { .. } => fcomponent::Error::Unsupported,
        }
    }

    /// Convert this error into its approximate `zx::Status` equivalent.
    pub fn as_zx_status(&self) -> zx::Status {
        match self {
            RunnerError::InvalidArgs { .. } => zx::Status::INVALID_ARGS,
            RunnerError::ComponentLoadError { .. } => zx::Status::UNAVAILABLE,
            RunnerError::ComponentLaunchError { .. } => zx::Status::UNAVAILABLE,
            RunnerError::ComponentRuntimeDirectoryError { .. } => zx::Status::INTERNAL,
            RunnerError::RunnerConnectionError { .. } => zx::Status::INTERNAL,
            RunnerError::Unsupported { .. } => zx::Status::NOT_SUPPORTED,
        }
    }
}

/// A null runner for components without a runtime environment.
///
/// Such environments, even though they don't execute any code, can still be
/// used by other components to bind to, which in turn may trigger further
/// bindings to its children.
pub(super) struct NullRunner {}

#[async_trait]
impl Runner for NullRunner {
    async fn start(
        &self,
        _start_info: fcrunner::ComponentStartInfo,
        server_end: ServerEnd<fcrunner::ComponentControllerMarker>,
    ) {
        spawn_null_controller_server(
            server_end
                .into_stream()
                .expect("NullRunner failed to convert server channel into request stream"),
        );
    }
}

/// Spawn an async execution context which takes ownership of `server_end`
/// and holds on to it until a stop or kill request is received.
fn spawn_null_controller_server(mut request_stream: fcrunner::ComponentControllerRequestStream) {
    // Listen to the ComponentController server end and exit after the first
    // one, as this is the contract we have implemented so far. Exiting will
    // cause our handle to the channel to drop and close the channel.
    fasync::Task::spawn(async move {
        while let Ok(Some(request)) = request_stream.try_next().await {
            match request {
                fcrunner::ComponentControllerRequest::Stop { control_handle: c } => {
                    c.shutdown();
                    break;
                }
                fcrunner::ComponentControllerRequest::Kill { control_handle: c } => {
                    c.shutdown();
                    break;
                }
            }
        }
    })
    .detach();
}

/// Wrapper for converting fcomponent::Error into the anyhow::Error type.
#[derive(Debug, Clone, Error)]
pub struct RemoteRunnerError(pub fcomponent::Error);

impl std::fmt::Display for RemoteRunnerError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        // Use the Debug formatter for Display.
        use std::fmt::Debug;
        self.0.fmt(f)
    }
}

impl std::convert::From<fcomponent::Error> for RemoteRunnerError {
    fn from(error: fcomponent::Error) -> RemoteRunnerError {
        RemoteRunnerError(error)
    }
}

/// A runner provided by another component.
pub struct RemoteRunner {
    client: fcrunner::ComponentRunnerProxy,
}

impl RemoteRunner {
    pub fn new(client: fcrunner::ComponentRunnerProxy) -> RemoteRunner {
        RemoteRunner { client }
    }
}

#[async_trait]
impl Runner for RemoteRunner {
    async fn start(
        &self,
        start_info: fcrunner::ComponentStartInfo,
        server_end: ServerEnd<fcrunner::ComponentControllerMarker>,
    ) {
        self.client.start(start_info, server_end).unwrap();
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use fidl::endpoints::{self, Proxy};

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_null_runner() {
        let null_runner = NullRunner {};
        let (client, server) =
            endpoints::create_endpoints::<fcrunner::ComponentControllerMarker>().unwrap();
        null_runner
            .start(
                fcrunner::ComponentStartInfo {
                    resolved_url: None,
                    program: None,
                    ns: None,
                    outgoing_dir: None,
                    runtime_dir: None,
                    ..fcrunner::ComponentStartInfo::EMPTY
                },
                server,
            )
            .await;
        let proxy = client.into_proxy().expect("failed converting to proxy");
        proxy.stop().expect("failed to send message to null runner");

        proxy.on_closed().await.expect("failed waiting for channel to close");
    }
}
