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

// Provides tools for generating a Rust library with D-Bus bindings. The generated bindings are
// included in the published crate since the source XML files are only available from the original
// path or the ebuild. See the README.md for usage.

use std::env;
use std::ffi::OsStr;
use std::fmt::{self, Debug, Display, Write as _};
use std::fs::{create_dir_all, remove_dir_all, File};
use std::io::{self, Write as _};
use std::path::{Path, PathBuf};
use std::process::Command;

pub const CROSSROADS_SERVER_OPTS: &[&str] = &["-s", "--crossroads"];
pub const TREE_SERVER_OPTS: &[&str] = &["-s", "-m", "Fn", "-a", "RefClosure"];

const DEFAULT_BINDINGS_DIR: &str = "src/bindings";
const DEFAULT_CLIENT_OPTS: &[&str] = &["-s", "-m", "None"];

#[derive(Debug, Clone, Eq, PartialEq)]
pub enum BindingsType<'a> {
    Client(Option<&'a [&'a str]>),
    Server(&'a [&'a str]),
    Both {
        client_opts: Option<&'a [&'a str]>,
        server_opts: &'a [&'a str],
    },
}

#[derive(Debug)]
pub enum Error {
    CleanupFailed(io::Error),
    CommandFailed(Option<i32>),
    Create(io::Error),
    CreateDirAll(io::Error),
    Generate(String),
    MissingCodegen(which::Error),
    Open(io::Error),
    SourceDoesntExist(PathBuf),
    Spawn(io::Error),
    Wait(io::Error),
    Write(io::Error),
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::Error::*;

        match self {
            CleanupFailed(e) => write!(f, "failed to cleanup old bindings: {}", e),
            CommandFailed(o) => match o {
                Some(c) => write!(f, "command failed with code {}", c),
                None => write!(f, "command failed"),
            },
            Create(e) => write!(f, "create failed: {}", e),
            CreateDirAll(e) => write!(f, "create_dir_all failed: {}", e),
            Generate(s) => write!(f, "generate failed: {}", s),
            MissingCodegen(e) => write!(f, "dbus-codegen-rust required, but not found: {:?}", e),
            Open(e) => write!(f, "open failed: {}", e),
            SourceDoesntExist(file) => match file.to_str() {
                None => write!(f, "empty path"),
                Some(s) => write!(f, "source file doesn't exist: {}", s),
            },
            Spawn(e) => write!(f, "spawn failed: {}", e),
            Wait(e) => write!(f, "wait failed: {}", e),
            Write(e) => write!(f, "write error: {}", e),
        }
    }
}

/// The result of an operation in this crate.
pub type Result<T> = std::result::Result<T, Error>;

// Include generated bindings.
fn include_module(mod_out: &mut File, module: &str) -> Result<()> {
    writeln!(
        mod_out,
        "  pub mod {module};\n  pub use {module}::*;",
        module = module
    )
    .map_err(Error::Write)
}

// sub_modules: &[(<module name>, <relative path to source xml>), ...]
pub fn generate_module(
    source_dir: &Path,
    sub_modules: &[(&str, &str, BindingsType)],
) -> Result<()> {
    let bindings_dir = PathBuf::from(DEFAULT_BINDINGS_DIR);
    let client_dir = bindings_dir.join("client");
    let server_dir = bindings_dir.join("server");

    let mut errors: String = String::new();

    // Check that dbus-bindgen-rust is available.
    let codegen = get_dbus_codgen()?;

    // If the bindings exist and it is a release build exit early.
    if bindings_dir.exists() {
        if env::var("PROFILE").map_or(false, |v| &v == "release") {
            return Ok(());
        }
        remove_dir_all(&bindings_dir).map_err(Error::CleanupFailed)?;
    }
    create_dir_all(&client_dir).map_err(Error::CreateDirAll)?;
    create_dir_all(&server_dir).map_err(Error::CreateDirAll)?;

    // Write header of include file.
    let mut mod_out =
        File::create(bindings_dir.join("include_modules.rs")).map_err(Error::Create)?;
    writeln!(
        mod_out,
        r#"// Do not edit. This is generated by system_api/build.rs.
#[allow(unused_imports)]
#[allow(clippy::all)]
pub mod client {{"#
    )
    .map_err(Error::Write)?;

    for (module, source, bindings_type) in sub_modules {
        let opts = match bindings_type {
            BindingsType::Client(client_opts) | BindingsType::Both { client_opts, .. } => {
                client_opts
            }
            BindingsType::Server(_) => {
                continue;
            }
        }
        .unwrap_or(DEFAULT_CLIENT_OPTS);
        // Generate bindings if they don't already exist.
        let destination = client_dir.join(format!("{}.rs", module));
        if !destination.exists() {
            if let Err(err) =
                generate_bindings(&codegen, &source_dir.join(source), &destination, opts)
            {
                writeln!(
                    errors,
                    "Failed to generate {:?} from {:?}: {}\n",
                    module, source, err
                )
                .ok();
                // Canonicalize will fail if the destination doesn't exist.
                continue;
            }
        }
        include_module(&mut mod_out, module)?;
    }
    writeln!(
        mod_out,
        r#"}}
#[allow(unused_imports)]
#[allow(clippy::all)]
pub mod server {{"#
    )
    .map_err(Error::Write)?;
    for (module, source, bindings_type) in sub_modules {
        let opts = *match bindings_type {
            BindingsType::Server(server_opts) | BindingsType::Both { server_opts, .. } => {
                server_opts
            }
            BindingsType::Client(_) => {
                continue;
            }
        };
        // Generate bindings if they don't already exist.
        let destination = server_dir.join(format!("{}.rs", module));
        if !destination.exists() {
            if let Err(err) =
                generate_bindings(&codegen, &source_dir.join(source), &destination, opts)
            {
                writeln!(
                    errors,
                    "Failed to generate {:?} from {:?}: {}",
                    module, source, err
                )
                .ok();
                // Canonicalize will fail if the destination doesn't exist.
                continue;
            }
        }
        include_module(&mut mod_out, module)?;
    }
    writeln!(mod_out, "}}").map_err(Error::Write)?;

    if errors.is_empty() {
        Ok(())
    } else {
        Err(Error::Generate(errors))
    }
}

fn get_dbus_codgen() -> Result<PathBuf> {
    let mut ret = which::which("dbus-codegen-rust").map_err(Error::MissingCodegen);
    if ret.is_err() {
        if let Some(dir) = std::env::var_os("HOME") {
            let alternative = Path::new(&dir).join(".cargo/bin/dbus-codegen-rust");
            if alternative.exists() {
                ret = Ok(alternative)
            }
        }
    }
    ret
}

fn generate_bindings<A: AsRef<OsStr>, S: AsRef<OsStr>, I: IntoIterator<Item = S>>(
    codegen: A,
    source: &Path,
    destination: &Path,
    opts: I,
) -> Result<()> {
    if !source.exists() {
        return Err(Error::SourceDoesntExist(source.to_path_buf()));
    }
    let status = Command::new(codegen)
        .args(opts)
        .stdin(File::open(source).map_err(Error::Open)?)
        .stdout(File::create(destination).map_err(Error::Create)?)
        .spawn()
        .map_err(Error::Spawn)?
        .wait()
        .map_err(Error::Wait)?;
    if !status.success() {
        return Err(Error::CommandFailed(status.code()));
    }
    Ok(())
}
