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

//! Tool for handling AVMD blobs.

use anyhow::{anyhow, bail, Result};
use apexutil::get_payload_vbmeta_image_hash;
use apkverify::pick_v4_apk_digest;
use avmd::{ApkDescriptor, Avmd, Descriptor, ResourceIdentifier, VbMetaDescriptor};
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
use serde::ser::Serialize;
use std::fs::File;
use vbmeta::VbMetaImage;

fn get_vbmeta_image_hash(file: &str) -> Result<Vec<u8>> {
    let img = VbMetaImage::verify_path(file)?;
    Ok(img.hash().ok_or_else(|| anyhow!("No hash as VBMeta image isn't signed"))?.to_vec())
}

/// Iterate over a set of argument values, that could be empty or come in
/// (<index>, <namespace>, <name>, <file>) tuple.
struct NamespaceNameFileIterator<'a> {
    indices: Option<clap::Indices<'a>>,
    values: Option<clap::Values<'a>>,
}

impl<'a> NamespaceNameFileIterator<'a> {
    fn new(args: &'a ArgMatches, name: &'a str) -> Self {
        NamespaceNameFileIterator { indices: args.indices_of(name), values: args.values_of(name) }
    }
}

impl<'a> Iterator for NamespaceNameFileIterator<'a> {
    type Item = (usize, &'a str, &'a str, &'a str);

    fn next(&mut self) -> Option<Self::Item> {
        match (self.indices.as_mut(), self.values.as_mut()) {
            (Some(indices), Some(values)) => {
                match (indices.nth(2), values.next(), values.next(), values.next()) {
                    (Some(index), Some(namespace), Some(name), Some(file)) => {
                        Some((index, namespace, name, file))
                    }
                    _ => None,
                }
            }
            _ => None,
        }
    }
}

fn create(args: &ArgMatches) -> Result<()> {
    // Store descriptors in the order they were given in the arguments
    // TODO: instead, group them by namespace?
    let mut descriptors = std::collections::BTreeMap::new();
    for (i, namespace, name, file) in NamespaceNameFileIterator::new(args, "vbmeta") {
        descriptors.insert(
            i,
            Descriptor::VbMeta(VbMetaDescriptor {
                resource: ResourceIdentifier::new(namespace, name),
                vbmeta_digest: get_vbmeta_image_hash(file)?,
            }),
        );
    }
    for (i, namespace, name, file) in NamespaceNameFileIterator::new(args, "apk") {
        let file = File::open(file)?;
        let (signature_algorithm_id, apk_digest) = pick_v4_apk_digest(file)?;
        descriptors.insert(
            i,
            Descriptor::Apk(ApkDescriptor {
                resource: ResourceIdentifier::new(namespace, name),
                signature_algorithm_id,
                apk_digest: apk_digest.to_vec(),
            }),
        );
    }
    for (i, namespace, name, file) in NamespaceNameFileIterator::new(args, "apex-payload") {
        descriptors.insert(
            i,
            Descriptor::VbMeta(VbMetaDescriptor {
                resource: ResourceIdentifier::new(namespace, name),
                vbmeta_digest: get_payload_vbmeta_image_hash(file)?,
            }),
        );
    }
    let avmd = Avmd::new(descriptors.into_values().collect());
    let mut bytes = Vec::new();
    avmd.serialize(
        &mut serde_cbor::Serializer::new(&mut serde_cbor::ser::IoWrite::new(&mut bytes))
            .packed_format()
            .legacy_enums(),
    )?;
    std::fs::write(args.value_of("file").unwrap(), &bytes)?;
    Ok(())
}

fn dump(args: &ArgMatches) -> Result<()> {
    let file = std::fs::read(args.value_of("file").unwrap())?;
    let avmd: Avmd = serde_cbor::from_slice(&file)?;
    println!("{}", avmd);
    Ok(())
}

fn main() -> Result<()> {
    let namespace_name_file = ["namespace", "name", "file"];
    let app = App::new("avmdtool")
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommand(
            SubCommand::with_name("create")
                .setting(AppSettings::ArgRequiredElseHelp)
                .arg(Arg::with_name("file").required(true).takes_value(true))
                .arg(
                    Arg::with_name("vbmeta")
                        .long("vbmeta")
                        .takes_value(true)
                        .value_names(&namespace_name_file)
                        .multiple(true),
                )
                .arg(
                    Arg::with_name("apk")
                        .long("apk")
                        .takes_value(true)
                        .value_names(&namespace_name_file)
                        .multiple(true),
                )
                .arg(
                    Arg::with_name("apex-payload")
                        .long("apex-payload")
                        .takes_value(true)
                        .value_names(&namespace_name_file)
                        .multiple(true),
                ),
        )
        .subcommand(
            SubCommand::with_name("dump")
                .setting(AppSettings::ArgRequiredElseHelp)
                .arg(Arg::with_name("file").required(true).takes_value(true)),
        );

    let args = app.get_matches();
    match args.subcommand() {
        Some(("create", sub_args)) => create(sub_args)?,
        Some(("dump", sub_args)) => dump(sub_args)?,
        _ => bail!("Invalid arguments"),
    }
    Ok(())
}
