use super::RULE;
use crate::log::instrument;

#[test]
fn ignore_properly_typed_input() {
    let good_code = r"
def double []: int -> int {
    $in * 2
}
";
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_properly_typed_output() {
    let good_code = r"
def create-list []: nothing -> list<int> {
    [1, 2, 3]
}
";
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_only_side_effect_pipeline_io() {
    instrument();
    let good_code = r#"
def "main postpone" [] {
  if (stop-timer) {
    print "Timer stopped - brightness adjustments postponed"
    print "Run 'solar-brightness resume' to restart and resume adjustments"
  } else {
    print "Failed to stop timer"
    exit 1
  }
}
"#;
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_assert() {
    instrument();
    let good_code = r#"
def "tests extract-time" [] {
  assert equal ("Sunrise is at: 2025-11-20 08:21:51 +01:00" | extract-time) "08:21:51"
  assert equal ("Civil dawn is at: 2025-11-20 07:44:37 +01:00" | extract-time) "07:44:37"
  assert equal ("Sunset is at: 2025-11-20 17:08:05 +01:00" | extract-time) "17:08:05"
}
"#;
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_fully_typed_pipeline() {
    let good_code = r"
def transform []: list<int> -> list<int> {
    $in | each { |x| $x + 1 }
}
";
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_union_type_signatures() {
    let good_code = r"
def stringify []: [
    int -> string
    float -> string
] {
    $in | into string
}
";
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_function_without_pipeline_usage() {
    let good_code = r"
def add [a: int, b: int]: nothing -> int {
    $a + $b
}
";
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_exported_function_with_types() {
    let good_code = r"
export def process []: string -> string {
    $in | str trim
}
";
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_typed_pipeline_with_params() {
    let good_code = r"
def multiply [factor: int]: int -> int {
    $in * $factor
}
";
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_function_returning_nothing() {
    let good_code = r"
def save-data [path: string]: any -> nothing {
    $in | save $path
}
";
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_string_to_record_conversion() {
    let good_code = r"
def parse-json []: string -> record {
    $in | from json
}
";
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_table_to_table_processing() {
    let good_code = r"
def filter-rows []: table -> table {
    $in | where size > 100
}
";
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_print_only_command() {
    let good_code = r#"
def main [] {
    print "Solar-based brightness manager"
    print "Use --help to see available subcommands"
}
"#;
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_side_effect_only_command() {
    let good_code = r#"
def setup [] {
    mkdir ~/.config/myapp
    print "Setup complete"
}
"#;
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_function_using_env_not_in() {
    let good_code = r#"
def get-cache-dir [name: string]: nothing -> string {
    let cache_dir = $"($env.HOME)/.cache/myapp"
    let session_dirs = (glob $"($cache_dir)/*/session_info/($name)")
    $session_dirs | first
}
"#;
    RULE.assert_ignores(good_code);
}

#[test]
fn ignore_function_using_nu_not_in() {
    let good_code = r#"
def get-config-path []: nothing -> string {
    $"($nu.home-path)/.config/myapp"
}
"#;
    RULE.assert_ignores(good_code);
}
