// Copyright 2022 The Fuchsia 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 crate::common::load_manifest;
use anyhow::{format_err, Context as _, Error};
use argh::FromArgs;
use config_client::cpp::{create_cpp_wrapper, CppSource, Flavor};
use std::{
    fs,
    io::Write,
    path::PathBuf,
    process::{Command as Process, Stdio},
};

#[derive(FromArgs, PartialEq, Debug)]
/// Generates a C++ client library from a given manifest.
/// This also requires a FIDL client library to be generated for the given manifest.
#[argh(subcommand, name = "cpp")]
pub struct GenerateCppSource {
    /// compiled manifest containing the config declaration
    #[argh(option)]
    cm: PathBuf,

    /// path to which to output a header file
    #[argh(option)]
    h_output: PathBuf,

    /// path to which to output a source file
    #[argh(option)]
    cc_output: PathBuf,

    /// namespace used by library
    #[argh(option)]
    namespace: String,

    /// name for the internal FIDL library
    #[argh(option)]
    fidl_library_name: String,

    /// path to clang-format binary
    #[argh(option)]
    clang_format: PathBuf,

    /// runner flavor to use ('elf' or 'driver')
    #[argh(option)]
    flavor: Flavor,
}

impl GenerateCppSource {
    pub fn generate(self) -> Result<(), Error> {
        let component = load_manifest(&self.cm).context("loading component manifest")?;
        let config_decl = component
            .config
            .as_ref()
            .ok_or_else(|| anyhow::format_err!("missing config declaration in manifest"))?;

        let CppSource { h_source, cc_source } =
            create_cpp_wrapper(config_decl, self.namespace, self.fidl_library_name, self.flavor)
                .context("creating cpp elf wrapper")?;

        let formatted_cc_source = format_source(&self.clang_format, cc_source)?;
        let formatted_h_source = format_source(&self.clang_format, h_source)?;

        // Make sure directories exist
        fs::create_dir_all(
            &self.cc_output.parent().expect("source output path must have a parent directory"),
        )
        .context("Failed to create directories for source files")?;

        let mut cc_out_file = fs::OpenOptions::new()
            .create(true)
            .truncate(true)
            .write(true)
            .open(&self.cc_output)
            .context("opening cc output file")?;
        cc_out_file.write(formatted_cc_source.as_bytes()).context("writing cc file to output")?;

        let mut h_out_file = fs::OpenOptions::new()
            .create(true)
            .truncate(true)
            .write(true)
            .open(&self.h_output)
            .context("opening h output file")?;
        h_out_file.write(formatted_h_source.as_bytes()).context("writing h file to output")?;

        Ok(())
    }
}

fn format_source(clang_format: &PathBuf, contents: String) -> Result<String, Error> {
    // TODO(fxbug.dev/49757) Use --style=file and copy the .clang-format file to the correct location.
    // An alternate way to do this is to load the config directly from .clang_format and put the
    // style as JSON in quotes.
    let mut process = Process::new(clang_format)
        .arg("--style=google")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .spawn()
        .context("could not spawn clang-format process")?;
    process
        .stdin
        .as_mut()
        .ok_or(format_err!("could not get stdin for clang-format process"))?
        .write_all(contents.as_bytes())
        .context("Could not write unformatted source to stdin of clang-format")?;
    let output =
        process.wait_with_output().context("could not wait for clang-format process to exit")?;

    if !output.status.success() {
        return Err(format_err!("failed to format cpp source: {:#?}", output));
    }

    let output = String::from_utf8(output.stdout)
        .context("output from clang-format is not UTF-8 compatible")?;
    Ok(output)
}
