/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//! compsvc is a service to run computational tasks in a PVM upon request. It is able to set up
//! file descriptors backed by fd_server and pass the file descriptors to the actual tasks for
//! read/write. The service also attempts to sandbox the execution so that one task cannot leak or
//! impact future tasks.
//!
//! Example:
//! $ compsvc /system/bin/sleep
//!
//! The current architecture / process hierarchy looks like:
//! - compsvc (handle requests)
//!   - compsvc_worker (for environment setup)
//!     - authfs (fd translation)
//!     - actual task

use anyhow::{bail, Context, Result};
use binder::unstable_api::AsNative;
use log::{debug, error};
use minijail::{self, Minijail};
use std::path::PathBuf;

use compos_aidl_interface::aidl::com::android::compos::ICompService::{
    BnCompService, ICompService,
};
use compos_aidl_interface::aidl::com::android::compos::Metadata::Metadata;
use compos_aidl_interface::binder::{
    add_service, BinderFeatures, Interface, ProcessState, Result as BinderResult, Status,
    StatusCode, Strong,
};

mod common;
use common::{SERVICE_NAME, VSOCK_PORT};

const WORKER_BIN: &str = "/apex/com.android.compos/bin/compsvc_worker";
// TODO: Replace with a valid directory setup in the VM.
const AUTHFS_MOUNTPOINT: &str = "/data/local/tmp";

struct CompService {
    worker_bin: PathBuf,
    task_bin: String,
    rpc_binder: bool,
    debuggable: bool,
}

impl CompService {
    pub fn new_binder(service: CompService) -> Strong<dyn ICompService> {
        BnCompService::new_binder(service, BinderFeatures::default())
    }

    fn run_worker_in_jail_and_wait(&self, args: &[String]) -> Result<(), minijail::Error> {
        let mut jail = Minijail::new()?;

        // TODO(b/185175567): New user and uid namespace when supported. Run as nobody.
        // New mount namespace to isolate the FUSE mount.
        jail.namespace_vfs();

        let inheritable_fds = if self.debuggable {
            vec![1, 2] // inherit/redirect stdout/stderr for debugging
        } else {
            vec![]
        };
        let _pid = jail.run(&self.worker_bin, &inheritable_fds, &args)?;
        jail.wait()
    }

    fn build_worker_args(&self, args: &[String], metadata: &Metadata) -> Vec<String> {
        let mut worker_args = vec![
            WORKER_BIN.to_string(),
            "--authfs-root".to_string(),
            AUTHFS_MOUNTPOINT.to_string(),
        ];
        for annotation in &metadata.input_fd_annotations {
            worker_args.push("--in-fd".to_string());
            worker_args.push(format!("{}:{}", annotation.fd, annotation.file_size));
        }
        for annotation in &metadata.output_fd_annotations {
            worker_args.push("--out-fd".to_string());
            worker_args.push(annotation.fd.to_string());
        }
        if self.debuggable {
            worker_args.push("--debug".to_string());
        }
        worker_args.push("--".to_string());

        // Do not accept arbitrary code execution. We want to execute some specific task of this
        // service. Use the associated executable.
        worker_args.push(self.task_bin.clone());
        worker_args.extend_from_slice(&args[1..]);
        worker_args
    }
}

impl Interface for CompService {}

impl ICompService for CompService {
    fn execute(&self, args: &[String], metadata: &Metadata) -> BinderResult<i8> {
        let worker_args = self.build_worker_args(args, metadata);

        match self.run_worker_in_jail_and_wait(&worker_args) {
            Ok(_) => Ok(0), // TODO(b/161471326): Sign the output on succeed.
            Err(minijail::Error::ReturnCode(exit_code)) => {
                error!("Task failed with exit code {}", exit_code);
                Err(Status::from(StatusCode::FAILED_TRANSACTION))
            }
            Err(e) => {
                error!("Unexpected error: {}", e);
                Err(Status::from(StatusCode::UNKNOWN_ERROR))
            }
        }
    }
}

fn parse_args() -> Result<CompService> {
    #[rustfmt::skip]
    let matches = clap::App::new("compsvc")
        .arg(clap::Arg::with_name("debug")
             .long("debug"))
        .arg(clap::Arg::with_name("task_bin")
             .required(true))
        .arg(clap::Arg::with_name("rpc_binder")
             .long("rpc-binder"))
        .get_matches();

    Ok(CompService {
        task_bin: matches.value_of("task_bin").unwrap().to_string(),
        worker_bin: PathBuf::from(WORKER_BIN),
        rpc_binder: matches.is_present("rpc_binder"),
        debuggable: matches.is_present("debug"),
    })
}

fn main() -> Result<()> {
    android_logger::init_once(
        android_logger::Config::default().with_tag("compsvc").with_min_level(log::Level::Debug),
    );

    let service = parse_args()?;

    if service.rpc_binder {
        let mut service = CompService::new_binder(service).as_binder();
        debug!("compsvc is starting as a rpc service.");
        // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
        // Plus the binder objects are threadsafe.
        let retval = unsafe {
            binder_rpc_unstable_bindgen::RunRpcServer(
                service.as_native_mut() as *mut binder_rpc_unstable_bindgen::AIBinder,
                VSOCK_PORT,
            )
        };
        if retval {
            debug!("RPC server has shut down gracefully");
            Ok(())
        } else {
            bail!("Premature termination of RPC server");
        }
    } else {
        ProcessState::start_thread_pool();
        debug!("compsvc is starting as a local service.");
        add_service(SERVICE_NAME, CompService::new_binder(service).as_binder())
            .with_context(|| format!("Failed to register service {}", SERVICE_NAME))?;
        ProcessState::join_thread_pool();
        bail!("Unexpected exit after join_thread_pool")
    }
}
