//! Integration tests for the `current` subcommand.
//!
//! Covers: retrieving the current scheme name, and querying individual
//! fields (variant, system, name, slug, author, description).
//!
//! Uses local fixture schemes — no network access required.

mod utils;

use anyhow::{ensure, Result};
use utils::{
    copy_dir_all, setup, write_to_file, ARTIFACTS_DIR, CURRENT_SCHEME_FILE_NAME, REPO_DIR,
    SCHEMES_REPO_NAME,
};

#[test]
fn test_cli_current_subcommand_with_setup() -> Result<()> {
    // -------
    // Arrange
    // -------
    let (_, data_path, command_vec, _temp_dir) =
        setup("test_cli_current_subcommand_with_setup", "current", true)?;
    let scheme_name = "base16-oceanicnext";
    let current_scheme_path = data_path.join(ARTIFACTS_DIR).join(CURRENT_SCHEME_FILE_NAME);
    let schemes_dir = data_path.join(format!("{REPO_DIR}/{SCHEMES_REPO_NAME}"));

    write_to_file(&current_scheme_path, scheme_name)?;
    copy_dir_all("./tests/fixtures/schemes", schemes_dir.join("base16"))?;

    // ---
    // Act
    // ---
    let (stdout, stderr) = utils::run_command(&command_vec)?;

    // ------
    // Assert
    // ------
    ensure!(stdout == format!("{scheme_name}\n"), "std not as expected");
    ensure!(stderr.is_empty(), "Expected empty stderr, got: {stderr}");

    Ok(())
}

#[test]
fn test_cli_current_subcommand_without_setup() -> Result<()> {
    // -------
    // Arrange
    // -------
    let (_, _data_path, command_vec, _temp_dir) =
        setup("test_cli_current_subcommand_without_setup", "current", true)?;

    // ---
    // Act
    // ---
    let (_, stderr) = utils::run_command(&command_vec)?;

    // ------
    // Assert
    // ------
    ensure!(
        stderr
            .contains("Failed to read last scheme from file. Try applying a scheme and try again."),
        "Expected stderr to contain 'Failed to read last scheme' message.\nGot: {stderr}"
    );

    Ok(())
}

#[test]
fn test_cli_current_subcommand_with_variant_existing() -> Result<()> {
    run_test_for_subcommand("variant", |output| output == "dark\n")
}

#[test]
fn test_cli_current_subcommand_with_system_existing() -> Result<()> {
    run_test_for_subcommand("system", |output| output == "base16\n")
}

#[test]
fn test_cli_current_subcommand_with_name_existing() -> Result<()> {
    run_test_for_subcommand("name", |output| output == "Tinty Generated\n")
}

#[test]
fn test_cli_current_subcommand_with_slug_existing() -> Result<()> {
    run_test_for_subcommand("slug", |output| output == "tinty-generated\n")
}

#[test]
fn test_cli_current_subcommand_with_description_not_existing() -> Result<()> {
    run_test_for_subcommand("description", |output| output == "\n")
}

#[test]
fn test_cli_current_subcommand_with_author_existing() -> Result<()> {
    run_test_for_subcommand("author", |output| output == "Tinty\n")
}

fn run_test_for_subcommand<F>(subcommand: &str, validate_output: F) -> Result<()>
where
    F: Fn(&str) -> bool,
{
    // -------
    // Arrange
    // -------
    let (_, data_path, command_vec, _temp_dir) = setup(
        &format!("test_cli_current_subcommand_with_{subcommand}_existing"),
        &format!("current {subcommand}"),
        false,
    )?;

    let scheme_name = "base16-tinty-generated";
    let current_scheme_path = data_path.join(format!("{ARTIFACTS_DIR}/{CURRENT_SCHEME_FILE_NAME}"));
    let schemes_dir = data_path.join(format!("{REPO_DIR}/{SCHEMES_REPO_NAME}"));

    write_to_file(&current_scheme_path, scheme_name)?;
    copy_dir_all("./tests/fixtures/schemes", schemes_dir.join("base16"))?;

    // ---
    // Act
    // ---
    let (stdout, stderr) = utils::run_command(&command_vec)?;

    // ------
    // Assert
    // ------
    ensure!(
        validate_output(&stdout),
        "stdout validation failed for subcommand '{subcommand}'.\nGot: {stdout}"
    );
    ensure!(stderr.is_empty(), "Expected empty stderr, got: {stderr}");

    Ok(())
}
