// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::collections::BTreeMap;
use std::env;
use std::fmt::Write as FmtWrite;
use std::fs;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};

/// Command that uses clang to parse a C++ file into its AST and outputs it as JSON. This is used
/// with the below jq script.
const CLANG_ARGS: &str = "-Xclang -ast-dump=json -fsyntax-only";

/// Script that recursively finds all objects with a `kind` field equal to `VarDecl` and extracts
/// the inner string literal. The output will be pairs of lines with the name followed by the value.
/// This is intended to be used with clangs' JSON formatted AST dump of a header file with string
/// constants.
const JQ_SCRIPT: &str = r#"'.. | select(.kind?=="VarDecl") | .name, .inner[0].value'"#;

/// Runs a shell command with `sh` and returns the stdout.
fn shell_helper(cmd: &str) -> String {
    let child = Command::new("sh")
        .arg("-c")
        .arg(cmd)
        .stdout(Stdio::piped())
        .spawn()
        .expect("Failed to start shell process");

    let output = child
        .wait_with_output()
        .expect("Failed to wait on shell process");

    if output.status.success() {
        String::from_utf8(output.stdout).expect("Failed to convert shell process output to String")
    } else {
        panic!("Failed shell command: {}", cmd);
    }
}

/// Converts a camel case a string such as `aVariableName` to upper snake case such as
/// `A_VARIABLE_NAME`.
fn upper_snake_case(input: &str) -> String {
    let mut output = String::new();
    for c in input.chars() {
        // Assumes that uppercase symbols indicate word breaks. Sort of gets confused by capitalized
        // acronyms.
        if c.is_ascii_uppercase() && !output.is_empty() {
            output.push('_')
        }
        output.push(c.to_ascii_uppercase());
    }
    output
}

/// Used to declare constant path information about system_api style APIs to parse and generate Rust
/// bindings for.
struct SystemApiDbus {
    path: &'static str,
    proto: Option<&'static str>,
}

impl SystemApiDbus {
    /// Declare a full D-Bus api with .proto and dbus-constants.h file.
    const fn new(path: &'static str, proto: &'static str) -> SystemApiDbus {
        SystemApiDbus {
            path,
            proto: Some(proto),
        }
    }

    /// Declare a full D-Bus api with only dbus-constants.h file under the given path. A path may
    /// also contain the relative file name if dbus-constants.h isn't the appropriate constants
    /// file.
    const fn constants(path: &'static str) -> SystemApiDbus {
        SystemApiDbus { path, proto: None }
    }

    /// Gets the include path in order to parse the .proto file for this API.
    fn get_include_path(&self, proto_root: &Path) -> impl AsRef<Path> {
        proto_root.join(self.path)
    }

    /// Gets the path to the .proto file for this API, if there is one.
    fn get_input_path(&self, proto_root: &Path) -> Option<PathBuf> {
        let proto = self.proto?;
        Some(proto_root.join(self.path).join(proto))
    }

    /// Parses the string constants in dbus-constants.h or the appropriate alternative header if
    /// appropriate. The given `constants` will be appended to with the name and value of each
    /// constant, converted to correct Rust style. If there are duplicate constant names, they will
    /// be overwritten.
    fn parse_constants(&self, proto_root: &Path, constants: &mut BTreeMap<String, String>) {
        let mut constants_path = proto_root.join(self.path);
        if !constants_path.is_file() {
            constants_path.push("dbus-constants.h");
            if !constants_path.is_file() {
                panic!("Failed to find header at {}", self.path);
            }
        }
        let clang = match env::var("CBUILD").ok() {
            Some(cbuild) => format!("{}-clang++", cbuild),
            None => "clang++".to_owned(),
        };
        let shell_parse_cmd = format!(
            r#"set -o pipefail && {} {} "{}" | jq -e -r {}"#,
            clang,
            CLANG_ARGS,
            constants_path.display(),
            JQ_SCRIPT,
        );
        let parse_output = shell_helper(&shell_parse_cmd);
        let mut lines = parse_output.lines();
        loop {
            if let (Some(var_name), Some(var_literal)) = (lines.next(), lines.next()) {
                if var_name.starts_with('k') {
                    let name = upper_snake_case(var_name.trim_matches('k'));
                    let value = var_literal.trim_matches('"').to_owned();
                    constants.insert(name, value);
                }
            } else {
                break;
            }
        }
    }
}

/// A list of system_api style APIs to generate Rust bindings for.
const APIS: &[SystemApiDbus] = &[
    SystemApiDbus::constants("dbus/debugd"),
    SystemApiDbus::constants("dbus/permission_broker"),
    // service_constants.h is the only header file needed that isn't called dbus_constants.h.
    SystemApiDbus::constants("dbus/service_constants.h"),
    SystemApiDbus::new("dbus/vm_concierge", "concierge_service.proto"),
    SystemApiDbus::new("dbus/vm_cicerone", "cicerone_service.proto"),
    SystemApiDbus::new("dbus/dlcservice", "dlcservice.proto"),
    SystemApiDbus::new("dbus/seneschal", "seneschal_service.proto"),
    SystemApiDbus::new("dbus/vm_plugin_dispatcher", "vm_plugin_dispatcher.proto"),
];

fn main() {
    let system_api_root = match env::var("SYSROOT") {
        Ok(path) => PathBuf::from(path).join("usr/include/chromeos"),
        // Make this work when typing "cargo build" in platform2/vm_tools/crostini_client
        Err(_) => PathBuf::from("../../system_api"),
    };

    let mut input_paths = Vec::new();
    let mut generator = protoc_rust::Codegen::new();
    let mut constants = Default::default();
    for api in APIS {
        // Some APIs have no .proto file that needs parsing.
        if let Some(input_path) = api.get_input_path(&system_api_root) {
            generator.input(&input_path);
            generator.include(api.get_include_path(&system_api_root));
            input_paths.push(input_path);
        }
        api.parse_constants(&system_api_root, &mut constants);
    }

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    generator.out_dir(&out_path);
    generator.run().expect("protoc");

    // Build up a string of code which gets included as the proto.rs module.
    let mut proto_include_code = String::new();
    // Collects all the Rust source files outputted by protoc as a series of modules.
    for input_file in input_paths.iter() {
        let stem = input_file.file_stem().unwrap().to_str().unwrap();
        let mod_path = out_path.join(format!("{}.rs", stem));
        writeln!(
            &mut proto_include_code,
            "#[path = \"{}\"]",
            mod_path.display()
        )
        .unwrap();
        writeln!(&mut proto_include_code, "pub mod {};", stem).unwrap();
    }

    // Also put all the collected string constants from `parse_constants` into the included module.
    for (name, value) in constants {
        writeln!(
            &mut proto_include_code,
            "pub const {}: &str = r###\"{}\"###;", // Uses Rust raw strings for safe inclusion.
            name, value
        )
        .unwrap();
    }

    // The proto_include.rs file gets included directly by proto.rs.
    let mut mod_out = fs::File::create(out_path.join("proto_include.rs")).unwrap();
    writeln!(mod_out, "pub mod system_api {{\n{}}}", proto_include_code).unwrap();
}
