//! Integration tests for the project-lifecycle CLI

#![allow(deprecated)]

use assert_cmd::Command;
use std::fs;
use tempfile::TempDir;

/// Create a temporary test directory with a valid lifecycle.toml config
fn create_test_fixture() -> TempDir {
    let temp_dir = TempDir::new().expect("Failed to create temp directory");
    let config_dir = temp_dir.path().join(".syntaxis");
    fs::create_dir_all(&config_dir).expect("Failed to create .syntaxis directory");

    let config_content = r#"project_type = "MultiLang"
mode = "Standalone"
primary_language = "rust"
languages = ["rust"]
phase = "Devel"

[project]
name = "test-project"
version = "0.1.0"
description = "Test project"
authors = ["Test Author"]
repository = ""
license = "MIT"
keywords = []
categories = []
created = "2025-11-12T00:00:00Z"
last_updated = "2025-11-12T00:00:00Z"

[phases]
allowed_transitions = []

[tools.tools.test_tool]
enabled = true
phases = ["Devel"]
mode = "Manual"
config = {}

[template_variables]
author_name = "Test Author"
org_name = "Test Org"
project_slug = "test-project"
repo_url = ""
docker_registry = ""
kubernetes_namespace = ""
artifact_registry = ""

[sbom]
enabled = true
format = "both"
include_transitive = true
include_dev = false
"#;

    let config_path = config_dir.join("config.toml");
    fs::write(&config_path, config_content).expect("Failed to write config file");

    temp_dir
}

#[test]
fn test_cli_help() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("--help");
    cmd.assert().success();
}

#[test]
fn test_init_command_help() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("init").arg("--help");
    cmd.assert().success();
}

#[test]
fn test_migrate_command_help() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("migrate").arg("--help");
    cmd.assert().success();
}

#[test]
fn test_security_command_help() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("security").arg("--help");
    cmd.assert().success();
}

#[test]
fn test_security_profile_help() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("security").arg("profile").arg("--help");
    cmd.assert().success();
}

#[test]
fn test_security_assess_help() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("security").arg("assess").arg("--help");
    cmd.assert().success();
}

#[test]
fn test_audit_command_help() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("audit").arg("--help");
    cmd.assert().success();
}

#[test]
fn test_phase_command_help() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("phase").arg("--help");
    cmd.assert().success();
}

#[test]
fn test_tool_command_help() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("tool").arg("--help");
    cmd.assert().success();
}

#[test]
fn test_checklist_command_help() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("checklist").arg("--help");
    cmd.assert().success();
}

#[test]
fn test_config_command_help() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("config").arg("--help");
    cmd.assert().success();
}

#[test]
fn test_status_command() {
    let fixture = create_test_fixture();
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.current_dir(fixture.path());
    cmd.arg("status");
    cmd.assert().success();
}

#[test]
fn test_security_profile_webapi() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("security").arg("profile").arg("webapi");
    cmd.assert()
        .success()
        .stdout(predicates::str::contains("webapi"));
}

#[test]
fn test_security_profile_invalid() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("security").arg("profile").arg("invalid");
    cmd.assert()
        .success()
        .stdout(predicates::str::contains("Unknown profile"));
}

#[test]
fn test_security_assess() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("security").arg("assess");
    cmd.assert()
        .success()
        .stdout(predicates::str::contains("Assessing security"));
}

#[test]
fn test_security_assess_detailed() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("security").arg("assess").arg("--detailed");
    cmd.assert()
        .success()
        .stdout(predicates::str::contains("DETAILED RECOMMENDATIONS"));
}

#[test]
fn test_audit_command() {
    // audit command requires configuration, so it will fail without a proper project setup
    // This is expected behavior - the command needs init and create to work
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("audit");
    // The command will fail because there's no config, which is correct
    cmd.assert().failure();
}

#[test]
fn test_verbose_flag() {
    let fixture = create_test_fixture();
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.current_dir(fixture.path());
    cmd.arg("--verbose").arg("status");
    cmd.assert().success();
}

#[test]
fn test_verbose_short_flag() {
    let fixture = create_test_fixture();
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.current_dir(fixture.path());
    cmd.arg("-v").arg("status");
    cmd.assert().success();
}

// Additional tests for handler-specific functionality

#[test]
fn test_migrate_command_with_path() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("migrate").arg(".");
    // This will fail because current directory isn't a valid project, but the command should parse
    let output = cmd.output().expect("Failed to execute command");
    // Either succeeds or fails due to directory content, not parsing
    assert!(output.status.code() == Some(0) || output.status.code() == Some(1));
}

#[test]
fn test_migrate_command_with_no_backup_flag() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("migrate").arg(".").arg("--no-backup");
    let output = cmd.output().expect("Failed to execute command");
    // Command should at least parse correctly
    assert!(output.status.code().is_some());
}

#[test]
fn test_security_profile_clitool() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("security").arg("profile").arg("clitool");
    cmd.assert().success();
}

#[test]
fn test_security_profile_dataprocessing() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("security").arg("profile").arg("dataprocessing");
    cmd.assert().success();
}

#[test]
fn test_security_profile_iot() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("security").arg("profile").arg("iot");
    cmd.assert().success();
}

#[test]
fn test_security_profile_ml() {
    let mut cmd = Command::cargo_bin("syntaxis").expect("Failed to get binary");
    cmd.arg("security").arg("profile").arg("ml");
    cmd.assert().success();
}
