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

//! Payload disk image

use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
    DiskImage::DiskImage, Partition::Partition, VirtualMachineAppConfig::DebugLevel::DebugLevel,
    VirtualMachineAppConfig::VirtualMachineAppConfig,
    VirtualMachineRawConfig::VirtualMachineRawConfig,
};
use android_system_virtualizationservice::binder::ParcelFileDescriptor;
use anyhow::{anyhow, Context, Result};
use binder::{wait_for_interface, Strong};
use log::{error, info};
use microdroid_metadata::{ApexPayload, ApkPayload, Metadata};
use microdroid_payload_config::{ApexConfig, VmPayloadConfig};
use once_cell::sync::OnceCell;
use packagemanager_aidl::aidl::android::content::pm::IPackageManagerNative::IPackageManagerNative;
use serde::Deserialize;
use serde_xml_rs::from_reader;
use std::env;
use std::fs::{File, OpenOptions};
use std::path::{Path, PathBuf};
use vmconfig::open_parcel_file;

/// The list of APEXes which microdroid requires.
// TODO(b/192200378) move this to microdroid.json?
const MICRODROID_REQUIRED_APEXES: [&str; 2] = ["com.android.adbd", "com.android.os.statsd"];

const APEX_INFO_LIST_PATH: &str = "/apex/apex-info-list.xml";

const PACKAGE_MANAGER_NATIVE_SERVICE: &str = "package_native";

/// Represents the list of APEXes
#[derive(Clone, Debug, Deserialize)]
struct ApexInfoList {
    #[serde(rename = "apex-info")]
    list: Vec<ApexInfo>,
}

#[derive(Clone, Debug, Deserialize)]
struct ApexInfo {
    #[serde(rename = "moduleName")]
    name: String,
    #[serde(rename = "modulePath")]
    path: PathBuf,

    #[serde(default)]
    boot_classpath: bool,
    #[serde(default)]
    systemserver_classpath: bool,
    #[serde(default)]
    dex2oatboot_classpath: bool,
}

impl ApexInfoList {
    /// Loads ApexInfoList
    fn load() -> Result<&'static ApexInfoList> {
        static INSTANCE: OnceCell<ApexInfoList> = OnceCell::new();
        INSTANCE.get_or_try_init(|| {
            let apex_info_list = File::open(APEX_INFO_LIST_PATH)
                .context(format!("Failed to open {}", APEX_INFO_LIST_PATH))?;
            let mut apex_info_list: ApexInfoList = from_reader(apex_info_list)
                .context(format!("Failed to parse {}", APEX_INFO_LIST_PATH))?;

            // For active APEXes, we refer env variables to see if it contributes to classpath
            let boot_classpath_apexes = find_apex_names_in_classpath_env("BOOTCLASSPATH");
            let systemserver_classpath_apexes =
                find_apex_names_in_classpath_env("SYSTEMSERVERCLASSPATH");
            let dex2oatboot_classpath_apexes =
                find_apex_names_in_classpath_env("DEX2OATBOOTCLASSPATH");
            for apex_info in apex_info_list.list.iter_mut() {
                apex_info.boot_classpath = boot_classpath_apexes.contains(&apex_info.name);
                apex_info.systemserver_classpath =
                    systemserver_classpath_apexes.contains(&apex_info.name);
                apex_info.dex2oatboot_classpath =
                    dex2oatboot_classpath_apexes.contains(&apex_info.name);
            }
            Ok(apex_info_list)
        })
    }

    /// Returns the list of apex names matching with the predicate
    fn get_matching(&self, predicate: fn(&ApexInfo) -> bool) -> Vec<String> {
        self.list.iter().filter(|info| predicate(info)).map(|info| info.name.clone()).collect()
    }

    fn get_path_for(&self, apex_name: &str) -> Result<PathBuf> {
        Ok(self
            .list
            .iter()
            .find(|apex| apex.name == apex_name)
            .ok_or_else(|| anyhow!("{} not found.", apex_name))?
            .path
            .clone())
    }
}

struct PackageManager {
    service: Strong<dyn IPackageManagerNative>,
    // TODO(b/199146189) use IPackageManagerNative
    apex_info_list: &'static ApexInfoList,
}

impl PackageManager {
    fn new() -> Result<Self> {
        let service = wait_for_interface(PACKAGE_MANAGER_NATIVE_SERVICE)
            .context("Failed to find PackageManager")?;
        let apex_info_list = ApexInfoList::load()?;
        Ok(Self { service, apex_info_list })
    }

    fn get_apex_list(&self, prefer_staged: bool) -> Result<ApexInfoList> {
        let mut list = self.apex_info_list.clone();
        if prefer_staged {
            // When prefer_staged, we override ApexInfo by consulting "package_native"
            let staged = self.service.getStagedApexModuleNames()?;
            for apex_info in list.list.iter_mut() {
                if staged.contains(&apex_info.name) {
                    let staged_apex_info = self.service.getStagedApexInfo(&apex_info.name)?;
                    if let Some(staged_apex_info) = staged_apex_info {
                        apex_info.path = PathBuf::from(staged_apex_info.diskImagePath);
                        // TODO(b/201788989) copy bootclasspath/systemserverclasspath
                    }
                }
            }
        }
        Ok(list)
    }
}

fn make_metadata_file(
    config_path: &str,
    apex_names: &[String],
    temporary_directory: &Path,
) -> Result<ParcelFileDescriptor> {
    let metadata_path = temporary_directory.join("metadata");
    let metadata = Metadata {
        version: 1,
        apexes: apex_names
            .iter()
            .enumerate()
            .map(|(i, apex_name)| ApexPayload {
                name: apex_name.clone(),
                partition_name: format!("microdroid-apex-{}", i),
                ..Default::default()
            })
            .collect(),
        apk: Some(ApkPayload {
            name: "apk".to_owned(),
            payload_partition_name: "microdroid-apk".to_owned(),
            idsig_partition_name: "microdroid-apk-idsig".to_owned(),
            ..Default::default()
        })
        .into(),
        payload_config_path: format!("/mnt/apk/{}", config_path),
        ..Default::default()
    };

    // Write metadata to file.
    let mut metadata_file = OpenOptions::new()
        .create_new(true)
        .read(true)
        .write(true)
        .open(&metadata_path)
        .with_context(|| format!("Failed to open metadata file {:?}", metadata_path))?;
    microdroid_metadata::write_metadata(&metadata, &mut metadata_file)?;

    // Re-open the metadata file as read-only.
    open_parcel_file(&metadata_path, false)
}

/// Creates a DiskImage with partitions:
///   metadata: metadata
///   microdroid-apex-0: apex 0
///   microdroid-apex-1: apex 1
///   ..
///   microdroid-apk: apk
///   microdroid-apk-idsig: idsig
fn make_payload_disk(
    apk_file: File,
    idsig_file: File,
    config_path: &str,
    vm_payload_config: &VmPayloadConfig,
    temporary_directory: &Path,
) -> Result<DiskImage> {
    let pm = PackageManager::new()?;
    let apex_list = pm.get_apex_list(vm_payload_config.prefer_staged)?;

    // collect APEX names from config
    let apexes = collect_apex_names(&apex_list, &vm_payload_config.apexes);
    info!("Microdroid payload APEXes: {:?}", apexes);

    let metadata_file = make_metadata_file(config_path, &apexes, temporary_directory)?;
    // put metadata at the first partition
    let mut partitions = vec![Partition {
        label: "payload-metadata".to_owned(),
        image: Some(metadata_file),
        writable: false,
    }];

    for (i, apex) in apexes.iter().enumerate() {
        let apex_path = apex_list.get_path_for(apex)?;
        let apex_file = open_parcel_file(&apex_path, false)?;
        partitions.push(Partition {
            label: format!("microdroid-apex-{}", i),
            image: Some(apex_file),
            writable: false,
        });
    }
    partitions.push(Partition {
        label: "microdroid-apk".to_owned(),
        image: Some(ParcelFileDescriptor::new(apk_file)),
        writable: false,
    });
    partitions.push(Partition {
        label: "microdroid-apk-idsig".to_owned(),
        image: Some(ParcelFileDescriptor::new(idsig_file)),
        writable: false,
    });

    Ok(DiskImage { image: None, partitions, writable: false })
}

fn find_apex_names_in_classpath_env(classpath_env_var: &str) -> Vec<String> {
    let val = env::var(classpath_env_var).unwrap_or_else(|e| {
        error!("Reading {} failed: {}", classpath_env_var, e);
        String::from("")
    });
    val.split(':')
        .filter_map(|path| {
            Path::new(path)
                .strip_prefix("/apex/")
                .map(|stripped| {
                    let first = stripped.iter().next().unwrap();
                    first.to_str().unwrap().to_string()
                })
                .ok()
        })
        .collect()
}

// Collect APEX names from config
fn collect_apex_names(apex_list: &ApexInfoList, apexes: &[ApexConfig]) -> Vec<String> {
    // Process pseudo names like "{BOOTCLASSPATH}".
    // For now we have following pseudo APEX names:
    // - {BOOTCLASSPATH}: represents APEXes contributing "BOOTCLASSPATH" environment variable
    // - {DEX2OATBOOTCLASSPATH}: represents APEXes contributing "DEX2OATBOOTCLASSPATH" environment variable
    // - {SYSTEMSERVERCLASSPATH}: represents APEXes contributing "SYSTEMSERVERCLASSPATH" environment variable
    let mut apex_names: Vec<String> = apexes
        .iter()
        .flat_map(|apex| match apex.name.as_str() {
            "{BOOTCLASSPATH}" => apex_list.get_matching(|apex| apex.boot_classpath),
            "{DEX2OATBOOTCLASSPATH}" => apex_list.get_matching(|apex| apex.dex2oatboot_classpath),
            "{SYSTEMSERVERCLASSPATH}" => apex_list.get_matching(|apex| apex.systemserver_classpath),
            _ => vec![apex.name.clone()],
        })
        .collect();
    // Add required APEXes
    apex_names.extend(MICRODROID_REQUIRED_APEXES.iter().map(|name| name.to_string()));
    apex_names.sort();
    apex_names.dedup();
    apex_names
}

pub fn add_microdroid_images(
    config: &VirtualMachineAppConfig,
    temporary_directory: &Path,
    apk_file: File,
    idsig_file: File,
    instance_file: File,
    vm_payload_config: &VmPayloadConfig,
    vm_config: &mut VirtualMachineRawConfig,
) -> Result<()> {
    vm_config.disks.push(make_payload_disk(
        apk_file,
        idsig_file,
        &config.configPath,
        vm_payload_config,
        temporary_directory,
    )?);

    let bootconfig_image = "/apex/com.android.virt/etc/microdroid_bootconfig.".to_owned()
        + match config.debugLevel {
            DebugLevel::NONE => "normal",
            DebugLevel::APP_ONLY => "app_debuggable",
            DebugLevel::FULL => "full_debuggable",
            _ => return Err(anyhow!("unsupported debug level: {:?}", config.debugLevel)),
        };
    vm_config.disks[1].partitions.push(Partition {
        label: "bootconfig".to_owned(),
        image: Some(open_parcel_file(Path::new(&bootconfig_image), false)?),
        writable: false,
    });

    // instance image is at the second partition in the second disk.
    vm_config.disks[1].partitions.push(Partition {
        label: "vm-instance".to_owned(),
        image: Some(ParcelFileDescriptor::new(instance_file)),
        writable: true,
    });

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_find_apex_names_in_classpath_env() {
        let key = "TEST_BOOTCLASSPATH";
        let classpath = "/apex/com.android.foo/javalib/foo.jar:/system/framework/framework.jar:/apex/com.android.bar/javalib/bar.jar";
        env::set_var(key, classpath);
        assert_eq!(
            find_apex_names_in_classpath_env(key),
            vec!["com.android.foo".to_owned(), "com.android.bar".to_owned()]
        );
    }
}
