// Copyright 2024 The Fuchsia Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use anyhow::Error;
use argh::FromArgs;
use std::collections::BTreeSet;
use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::path::PathBuf;
use std::process::Command;

/// Tool that run the aidl tool

/// Arguments for aidl_wrapper.
#[derive(Debug, FromArgs)]
pub struct AidlWrapperArgs {
    /// path to the aidl tool
    #[argh(option)]
    pub aidl_path: PathBuf,

    /// base paths for the library
    #[argh(option)]
    pub base: Vec<PathBuf>,

    /// directory into which the tool will generate the dependencies and package files
    #[argh(option)]
    dependency_dir: PathBuf,

    /// dependency dir of dependencies
    #[argh(option)]
    deps: Vec<PathBuf>,

    /// arguments of the aidl command
    #[argh(option)]
    pub args: Vec<String>,

    /// file containing the input of the aidl command
    #[argh(option)]
    pub inputs_path: PathBuf,

    /// the version of the interface and parcelable
    #[argh(option)]
    version: Option<String>,
}

fn read_file<T>(filename: PathBuf) -> Result<T, Error>
where
    T: FromIterator<String>,
{
    // Open the file in read-only mode.
    let file = File::open(filename)?;
    // Read the file line by line.
    Ok(BufReader::new(file).lines().collect::<Result<T, _>>()?)
}

fn read_path_bufs(filename: PathBuf) -> Result<BTreeSet<PathBuf>, Error> {
    Ok(read_file::<BTreeSet<String>>(filename)?.iter().map(PathBuf::from).collect())
}

fn write_file<'a, T>(filename: PathBuf, content: impl Iterator<Item = T>) -> Result<(), Error>
where
    String: From<T>,
{
    std::fs::OpenOptions::new()
        .create(true)
        .truncate(true)
        .write(true)
        .open(filename)?
        .write_all(content.map(String::from).collect::<Vec<_>>().join("\n").as_bytes())?;
    Ok(())
}

const DEPS_FILE: &'static str = "deps.d";
const PACKAGE_FILE: &'static str = "aidl_package";
const BASES_FILE: &'static str = "aidl_bases";
const RUST_GLUE_ARGS: &'static str = "aidl_rust_glue_args";
const HASH_FILE: &'static str = ".hash";

fn main() -> Result<(), Error> {
    let opt: AidlWrapperArgs = argh::from_env();
    let mut packages = BTreeSet::<String>::new();
    let mut dependencies = BTreeSet::<PathBuf>::new();
    for base in &opt.base {
        dependencies.insert(base.clone());
    }
    let mut glue_args = vec![];
    for deps in opt.deps {
        for package in read_file::<BTreeSet<String>>(deps.join(PACKAGE_FILE))? {
            glue_args.push("-I".to_owned());
            glue_args.push(package.replace(".", "_").to_owned());
        }
        for base in read_file::<BTreeSet<String>>(deps.join(BASES_FILE))? {
            dependencies.insert(base.into());
        }
    }
    for path in read_path_bufs(opt.inputs_path)? {
        let mut hash = None;
        for base in &opt.base {
            if path.starts_with(base) {
                let package = pathdiff::diff_paths(&path, &base)
                    .unwrap()
                    .parent()
                    .unwrap()
                    .to_string_lossy()
                    .replace("/", ".");
                packages.insert(package);
                if opt.version.is_some() {
                    let mut hashes = read_file::<Vec<String>>(base.join(HASH_FILE))?;
                    hash = hashes.pop();
                }
            }
        }
        let mut command = Command::new(&opt.aidl_path);
        // Make aidl generate a dependencies file.
        command.arg("-a");
        for dep in &dependencies {
            command.arg("-I").arg(dep);
        }
        if let Some(version) = &opt.version {
            command.arg(format!("--version={version}"));
        }
        if let Some(hash) = hash {
            command.arg(format!("--hash={hash}"));
        }
        for arg in &opt.args {
            command.arg(arg);
        }
        command.arg(path);
        let output = command.output()?;
        if !output.status.success() {
            anyhow::bail!("aidl failed: {output:?}");
        }
    }

    // Find dependency files, aggregate it and delete the individual dependencies.
    let mut aggregated_dependency_file = vec![];
    for entry in walkdir::WalkDir::new(&opt.dependency_dir).into_iter() {
        let entry = entry?;
        let f_name = entry.file_name().to_string_lossy();

        if f_name.ends_with(".d") {
            let file = File::open(entry.path())?;
            aggregated_dependency_file
                .append(&mut BufReader::new(file).lines().collect::<Result<Vec<_>, _>>()?);
            std::fs::remove_file(entry.path())?;
        }
    }
    write_file(opt.dependency_dir.join(PACKAGE_FILE), packages.into_iter())?;
    write_file(opt.dependency_dir.join(RUST_GLUE_ARGS), glue_args.iter().map(|x| x.as_str()))?;
    write_file(opt.dependency_dir.join(DEPS_FILE), aggregated_dependency_file.into_iter())?;
    write_file(
        opt.dependency_dir.join(BASES_FILE),
        dependencies.iter().map(|x| x.to_string_lossy()),
    )?;
    Ok(())
}
