// 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::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,
    )?);

    if config.debug {
        vm_config.disks[1].partitions.push(Partition {
            label: "bootconfig".to_owned(),
            image: Some(open_parcel_file(
                Path::new("/apex/com.android.virt/etc/microdroid_bootconfig.debug"),
                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()]
        );
    }
}
