use anyhow::Result;
use std::process::Command;

use crate::config::ClangTidyConfig;
use crate::graph::Product;
use crate::processors::{run_command, check_command_output};

pub struct ClangTidyProcessor {
    config: ClangTidyConfig,
}

impl ClangTidyProcessor {
    pub fn new(config: ClangTidyConfig) -> Self {
        Self { config }
    }

    fn execute_product(&self, product: &Product) -> Result<()> {
        let mut cmd = Command::new("clang-tidy");
        for arg in &self.config.args {
            cmd.arg(arg);
        }
        cmd.arg(product.primary_input());
        // Add -- to separate clang-tidy args from compiler args
        cmd.arg("--");
        for arg in &self.config.compiler_args {
            cmd.arg(arg);
        }

        let output = run_command(&mut cmd)?;
        check_command_output(&output, "clang-tidy")
    }
}

impl_checker!(ClangTidyProcessor,
    config: config,
    description: "Run clang-tidy static analysis on C/C++ source files",
    name: crate::processors::names::CLANG_TIDY,
    execute: execute_product,
    guard: scan_root,
    tools: ["clang-tidy".to_string()],
    config_json: true,
);
