// Copyright 2021 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 {
    super::{error::ElfRunnerError, runtime_dir::RuntimeDirectory},
    async_trait::async_trait,
    fidl::endpoints::Proxy,
    fidl_fuchsia_process_lifecycle::LifecycleProxy,
    fuchsia_async as fasync,
    fuchsia_zircon::{self as zx, AsHandleRef, Job, Process, Task},
    futures::future::{BoxFuture, FutureExt},
    log::{error, warn},
    runner::component::Controllable,
    std::sync::Arc,
};

/// Structure representing a running elf component.
pub struct ElfComponent {
    /// Namespace directory for this component, kept just as a reference to
    /// keep the namespace alive.
    _runtime_dir: RuntimeDirectory,

    /// Job in which the underlying process that represents the component is
    /// running.
    job: Arc<Job>,

    /// Process made for the program binary defined for this component.
    process: Option<Arc<Process>>,

    /// Client end of the channel given to an ElfComponent which says it
    /// implements the Lifecycle protocol. If the component does not implement
    /// the protocol, this will be None.
    lifecycle_channel: Option<LifecycleProxy>,

    /// We need to remember if we marked the main process as critical, because if we're asked to
    /// kill a component that has such a marking it'll bring down everything.
    main_process_critical: bool,

    /// Any tasks spawned to serve this component. For example, stdout and stderr
    /// listeners are Task objects that live for the duration of the component's
    /// lifetime.
    _tasks: Vec<fasync::Task<()>>,

    /// URL with which the component was launched.
    component_url: String,
}

impl ElfComponent {
    pub fn new(
        _runtime_dir: RuntimeDirectory,
        job: Job,
        process: Process,
        lifecycle_channel: Option<LifecycleProxy>,
        main_process_critical: bool,
        tasks: Vec<fasync::Task<()>>,
        component_url: String,
    ) -> Self {
        Self {
            _runtime_dir,
            job: Arc::new(job),
            process: Some(Arc::new(process)),
            lifecycle_channel,
            main_process_critical,
            _tasks: tasks,
            component_url,
        }
    }

    /// Return a pointer to the Process, returns None if the component has no
    /// Process.
    pub fn copy_process(&self) -> Option<Arc<Process>> {
        self.process.clone()
    }

    /// Return a handle to the Job containing the process for this component.
    ///
    /// The rights of the job will be set such that the resulting handle will be apppropriate to
    /// use for diagnostics-only purposes. Right now that is ZX_RIGHTS_BASIC (which includes
    /// INSPECT).
    pub fn copy_job_for_diagnostics(&self) -> Result<Job, ElfRunnerError> {
        self.job.as_handle_ref().duplicate(zx::Rights::BASIC).map(|h| Job::from(h)).map_err(
            |status| {
                ElfRunnerError::component_job_duplication_error(self.component_url.clone(), status)
            },
        )
    }
}

#[async_trait]
impl Controllable for ElfComponent {
    async fn kill(mut self) {
        if self.main_process_critical {
            warn!("killing a component with 'main_process_critical', so this will also kill component_manager and all of its components");
        }
        let _ = self.job.kill().map_err(|e| error!("failed killing job during kill: {}", e));
    }

    fn stop<'a>(&mut self) -> BoxFuture<'a, ()> {
        if let Some(lifecycle_chan) = self.lifecycle_channel.take() {
            let _ = lifecycle_chan.stop();

            let job = self.job.clone();

            // If the component's main process is critical we must watch for
            // the main process to exit, otherwise we could end up killing that
            // process and therefore killing the root job.
            if self.main_process_critical {
                if self.process.is_none() {
                    // This is a bit strange because there's no process, but there is a lifecycle
                    // channel. Since there is no process it seems like killing it can't kill
                    // component manager.
                    warn!("killing job of component with 'main_process_critical' set because component has lifecycle channel, but no process main process.");
                    let _ = self.job.kill().map_err(|e| {
                        error!("failed killing job for component with no lifecycle channel: {}", e)
                    });
                    return async {}.boxed();
                }
                // Try to duplicate the Process handle so we can us it to wait for
                // process termination
                let proc_handle = self.process.take().unwrap();

                async move {
                    let _ = fasync::OnSignals::new(
                        &proc_handle.as_handle_ref(),
                        zx::Signals::PROCESS_TERMINATED,
                    )
                    .await
                    .map_err(|e| {
                        error!(
                        "killing component's job after failure waiting on process exit, err: {}",
                        e
                    )
                    });
                    let _ = job.kill().map_err(|e| {
                        error!("failed killing job in stop after lifecycle channel closed: {}", e)
                    });
                }
                .boxed()
            } else {
                async move {
                    let _ = lifecycle_chan.on_closed()
                    .await
                    .map_err(|e| {
                        error!(
                        "killing component's job after failure waiting on lifecycle channel, err: {}",
                        e
                        )
                    });
                    let _ = job.kill().map_err(|e| {
                        error!("failed killing job in stop after lifecycle channel closed: {}", e)
                    });
                }
                .boxed()
            }
        } else {
            let _ = self.job.kill().map_err(|e| {
                error!("failed killing job for component with no lifecycle channel: {}", e)
            });
            async {}.boxed()
        }
    }
}

impl Drop for ElfComponent {
    fn drop(&mut self) {
        // just in case we haven't killed the job already
        let _ = self.job.kill().map_err(|e| error!("failed to kill job in drop: {}", e));
    }
}
