use crate::{
    load,
    progress::{DumbConsoleProgress, FancyConsoleProgress, Progress},
    terminal, trace, work,
};
use anyhow::anyhow;
use std::path::Path;

fn build(
    options: work::Options,
    build_filename: String,
    targets: Vec<String>,
    verbose: bool,
) -> anyhow::Result<Option<usize>> {
    let (mut dumb_console, mut fancy_console);
    let progress: &mut dyn Progress = if terminal::use_fancy() {
        fancy_console = FancyConsoleProgress::new(verbose);
        &mut fancy_console
    } else {
        dumb_console = DumbConsoleProgress::new(verbose);
        &mut dumb_console
    };

    let mut state = trace::scope("load::read", || load::read(&build_filename))?;
    let mut work = work::Work::new(
        state.graph,
        state.hashes,
        state.db,
        &options,
        progress,
        state.pools,
    );

    let mut tasks_finished = 0;

    // Attempt to rebuild build.ninja.
    let build_file_target = work.lookup(&build_filename);
    if let Some(target) = build_file_target {
        work.want_file(target)?;
        match trace::scope("work.run", || work.run())? {
            None => return Ok(None),
            Some(0) => {
                // build.ninja already up to date.
                // TODO: this logic is not right in the case where a build has
                // a step that doesn't touch build.ninja.  We should instead
                // verify the specific FileId was updated.
            }
            Some(n) => {
                // Regenerated build.ninja; start over.
                tasks_finished = n;
                state = trace::scope("load::read", || load::read(&build_filename))?;
                work = work::Work::new(
                    state.graph,
                    state.hashes,
                    state.db,
                    &options,
                    progress,
                    state.pools,
                );
            }
        }
    }

    if !targets.is_empty() {
        for name in &targets {
            let target = work
                .lookup(name)
                .ok_or_else(|| anyhow::anyhow!("unknown path requested: {:?}", name))?;
            if Some(target) == build_file_target {
                // Already built above.
                continue;
            }
            work.want_file(target)?;
        }
    } else if !state.default.is_empty() {
        for target in state.default {
            work.want_file(target)?;
        }
    } else {
        work.want_every_file(build_file_target)?;
    }

    let tasks = trace::scope("work.run", || work.run())?;
    // Include any tasks from initial build in final count of steps.
    Ok(tasks.map(|n| n + tasks_finished))
}

fn default_parallelism() -> anyhow::Result<usize> {
    // Ninja uses available processors + a constant, but I don't think the
    // difference matters too much.
    let par = std::thread::available_parallelism()?;
    Ok(usize::from(par))
}

#[derive(argh::FromArgs)] // this struct generates the flags and --help output
/// n2, a ninja compatible build system
struct Args {
    /// chdir before running
    #[argh(option, short = 'C')]
    chdir: Option<String>,

    /// input build file [default=build.ninja]
    #[argh(option, short = 'f', default = "(\"build.ninja\".into())")]
    build_file: String,

    /// debugging tools
    #[argh(option, short = 'd')]
    debug: Option<String>,

    /// subcommands
    #[argh(option, short = 't')]
    tool: Option<String>,

    /// parallelism [default uses system thread count]
    #[argh(option, short = 'j')] // tododefault_parallelism()")]
    parallelism: Option<usize>,

    /// keep going until at least N failures (0 means infinity) [default=1]
    #[argh(option, short = 'k', default = "1")]
    keep_going: usize,

    /// print version (required by cmake)
    #[argh(switch, hidden_help)]
    version: bool,

    /// compdb flag (required by meson)
    #[allow(dead_code)]
    #[argh(switch, short = 'x', hidden_help)]
    expand_rspfile: bool,

    /// print executed command lines
    #[argh(switch, short = 'v')]
    verbose: bool,

    /// targets to build
    #[argh(positional)]
    targets: Vec<String>,
}

fn run_impl() -> anyhow::Result<i32> {
    let mut fake_ninja_compat = Path::new(&std::env::args().next().unwrap())
        .file_name()
        .unwrap()
        == std::ffi::OsStr::new(&format!("ninja{}", std::env::consts::EXE_SUFFIX));

    let args: Args = argh::from_env();

    let mut options = work::Options {
        parallelism: match args.parallelism {
            Some(p) => p,
            None => default_parallelism()?,
        },
        failures_left: Some(args.keep_going).filter(|&n| n > 0),
        explain: false,
        adopt: false,
    };

    if let Some(dir) = args.chdir {
        let dir = Path::new(&dir);
        std::env::set_current_dir(dir).map_err(|err| anyhow!("chdir {:?}: {}", dir, err))?;
    }

    if let Some(debug) = args.debug {
        match debug.as_str() {
            "ninja_compat" => fake_ninja_compat = true,
            "explain" => options.explain = true,
            "list" => {
                println!("debug tools:");
                println!("  explain  print why each target is considered out of date");
                println!("  trace    generate json performance trace");
                return Ok(1);
            }
            "trace" => trace::open("trace.json")?,
            _ => anyhow::bail!("unknown -d {:?}, use -d list to list", debug),
        }
    }

    if args.version {
        if fake_ninja_compat {
            // CMake requires a particular Ninja version.
            println!("1.10.2");
            return Ok(0);
        } else {
            println!("{}", env!("CARGO_PKG_VERSION"));
        }
        return Ok(0);
    }

    if let Some(tool) = args.tool {
        match tool.as_str() {
            "list" => {
                println!("subcommands:");
                println!("  (none yet, but see README if you're looking here trying to get CMake to work)");
                return Ok(1);
            }
            "compdb" if fake_ninja_compat => {
                // meson wants to invoke this tool.
                return Ok(0); // do nothing; TODO
            }
            "recompact" if fake_ninja_compat => {
                // CMake unconditionally invokes this tool, yuck.
                return Ok(0); // do nothing
            }
            "restat" if fake_ninja_compat => {
                // CMake invokes this after generating build files; mark build
                // targets as up to date by running the build with "adopt" flag
                // on.
                options.adopt = true;
            }
            _ => {
                anyhow::bail!("unknown -t {:?}, use -t list to list", tool);
            }
        }
    }

    match build(options, args.build_file, args.targets, args.verbose)? {
        None => {
            // Don't print any summary, the failing task is enough info.
            return Ok(1);
        }
        Some(0) => {
            // Special case: don't print numbers when no work done.
            println!("n2: no work to do");
        }
        Some(n) => {
            println!(
                "n2: ran {} task{}, now up to date",
                n,
                if n == 1 { "" } else { "s" }
            );
        }
    }

    Ok(0)
}

pub fn run() -> anyhow::Result<i32> {
    let res = run_impl();
    trace::close();
    res
}
