//! > Test ignoring of test config in the test config.

//! > test_runner_name
test_expand_plugin(expect_diagnostics: false)

//! > cfg
["a", "b", ["k", "a"], ["k", "b"]]

//! > cairo_code
fn f0() -> felt252 {
    0
}

#[cfg(a)]
fn f1() -> felt252 {
    0
}

#[cfg(X)]
fn f2() -> felt252 {
    0
}

#[cfg(k: 'a')]
fn f3() -> felt252 {
    0
}

#[cfg(k: 'X')]
fn f4() -> felt252 {
    0
}

#[cfg(a, b)]
fn f5() -> felt252 {
    0
}

#[cfg(a, b, c)]
fn f6() -> felt252 {
    0
}

#[cfg(k: 'a', k: 'b')]
fn f7() -> felt252 {
    0
}

#[cfg(k: 'a', k: 'b', k: 'c')]
fn f8() -> felt252 {
    0
}

#[cfg(a)]
#[cfg(b)]
fn f9() -> felt252 {
    0
}

#[cfg(a)]
#[cfg(c)]
#[cfg(b)]
fn f10() -> felt252 {
    0
}

#[cfg(no_cfg)]
#[unsupported_attr]
fn f11() -> felt252 {
    0
}

trait RemoveTraitItem {
    fn f0();
    #[cfg(a)]
    fn f1();
    #[cfg(X)]
    fn f2();
    #[cfg(k: 'a')]
    fn f3();
    #[cfg(k: 'X')]
    fn f4();
    #[cfg(a, b)]
    fn f5();
    #[cfg(a, b, c)]
    fn f6();
    #[cfg(k: 'a', k: 'b')]
    fn f7();
    #[cfg(k: 'a', k: 'b', k: 'c')]
    fn f8();
    #[cfg(a)]
    #[cfg(b)]
    fn f9();
    #[cfg(a)]
    #[cfg(c)]
    #[cfg(b)]
    fn f10();
}

impl RemoveTraitItem of SomeTrait {
    fn f0() {}
    #[cfg(a)]
    fn f1() {}
    #[cfg(X)]
    fn f2() {}
    #[cfg(k: 'a')]
    fn f3() {}
    #[cfg(k: 'X')]
    fn f4() {}
    #[cfg(a, b)]
    fn f5() {}
    #[cfg(a, b, c)]
    fn f6() {}
    #[cfg(k: 'a', k: 'b')]
    fn f7() {}
    #[cfg(k: 'a', k: 'b', k: 'c')]
    fn f8() {}
    #[cfg(a)]
    #[cfg(b)]
    fn f9() {}
    #[cfg(a)]
    #[cfg(c)]
    #[cfg(b)]
    fn f10() {}
}

mod remove_module_item {
    fn f0() -> felt252 {
        0
    }
    #[cfg(a)]
    fn f1() -> felt252 {
        0
    }
    #[cfg(X)]
    fn f2() -> felt252 {
        0
    }
    #[cfg(k: 'a')]
    fn f3() -> felt252 {
        0
    }
    #[cfg(k: 'X')]
    fn f4() -> felt252 {
        0
    }
    #[cfg(a, b)]
    fn f5() -> felt252 {
        0
    }
    #[cfg(a, b, c)]
    fn f6() -> felt252 {
        0
    }
    #[cfg(k: 'a', k: 'b')]
    fn f7() -> felt252 {
        0
    }
    #[cfg(k: 'a', k: 'b', k: 'c')]
    fn f8() -> felt252 {
        0
    }
    #[cfg(a)]
    #[cfg(b)]
    fn f9() -> felt252 {
        0
    }
    #[cfg(a)]
    #[cfg(c)]
    #[cfg(b)]
    fn f10() -> felt252 {
        0
    }
}

//! > expanded_cairo_code
fn f0() -> felt252 {
    0
}

#[cfg(a)]
fn f1() -> felt252 {
    0
}

#[cfg(k: 'a')]
fn f3() -> felt252 {
    0
}

#[cfg(a, b)]
fn f5() -> felt252 {
    0
}

#[cfg(k: 'a', k: 'b')]
fn f7() -> felt252 {
    0
}

#[cfg(a)]
#[cfg(b)]
fn f9() -> felt252 {
    0
}

mod remove_module_item {
    fn f0() -> felt252 {
        0
    }
    #[cfg(a)]
    fn f1() -> felt252 {
        0
    }
    #[cfg(k: 'a')]
    fn f3() -> felt252 {
        0
    }
    #[cfg(a, b)]
    fn f5() -> felt252 {
        0
    }
    #[cfg(k: 'a', k: 'b')]
    fn f7() -> felt252 {
        0
    }
    #[cfg(a)]
    #[cfg(b)]
    fn f9() -> felt252 {
        0
    }
}

trait RemoveTraitItem {
    fn f0();
    #[cfg(a)]
    fn f1();
    #[cfg(k: 'a')]
    fn f3();
    #[cfg(a, b)]
    fn f5();
    #[cfg(k: 'a', k: 'b')]
    fn f7();
    #[cfg(a)]
    #[cfg(b)]
    fn f9();
}

impl RemoveTraitItem of SomeTrait {
    fn f0() {}
    #[cfg(a)]
    fn f1() {}
    #[cfg(k: 'a')]
    fn f3() {}
    #[cfg(a, b)]
    fn f5() {}
    #[cfg(k: 'a', k: 'b')]
    fn f7() {}
    #[cfg(a)]
    #[cfg(b)]
    fn f9() {}
}

//! > expected_diagnostics

//! > ==========================================================================

//! > Test logical operators in config attributes.

//! > test_runner_name
test_expand_plugin(expect_diagnostics: false)

//! > cfg
["a", "b", ["k", "a"], ["k", "b"]]

//! > cairo_code
#[cfg(not(a))]
fn f1() -> felt252 {
    0
}

#[cfg(not(b))]
fn f2() -> felt252 {
    0
}

#[cfg(not(k: "a"))]
fn f3() -> felt252 {
    0
}

#[cfg(and(a, b))]
fn f4() -> felt252 {
    0
}

#[cfg(or(a, x))]
fn f5() -> felt252 {
    0
}

//! > expanded_cairo_code

#[cfg(and(a, b))]
fn f4() -> felt252 {
    0
}

#[cfg(or(a, x))]
fn f5() -> felt252 {
    0
}

//! > expected_diagnostics

//! > ==========================================================================

//! > Test more complex logical operators in config attributes.

//! > test_runner_name
test_expand_plugin(expect_diagnostics: false)

//! > cfg
["a", "b", ["k", "a"], ["k", "b"], "c", "d"]

//! > cairo_code
#[cfg(and(or(a, b), not(and(k: "a", k: "b"))))]
fn f_nested_and_or() -> felt252 {
    0
}

#[cfg(or(and(a, b), and(k: "a", not(k: "b"))))]
fn f_nested_or_and() -> felt252 {
    0
}

#[cfg(and(or(not(a), b), not(and(k: "a", c))))]
fn f_combined_not_and_or() -> felt252 {
    0
}

#[cfg(and(or(and(a, not(b)), not(k: "a")), or(k: "b", and(c, d))))]
fn f_mixed_conditions() -> felt252 {
    0
}

#[cfg(not(or(and(a, b), not(k: "b"))))]
fn f_not_over_nested() -> felt252 {
    0
}

#[cfg(or(and(a, not(b)), and(k: "a", not(c))))]
fn f_multiple_conditions() -> felt252 {
    0
}

#[cfg(and(or(and(a, b), not(c)), or(not(k: "a"), k: "b")))]
fn f_deep_nested() -> felt252 {
    0
}

#[cfg(or(not(and(a, not(b))), and(k: "a", or(k: "b", c))))]
fn f_complex_evaluation() -> felt252 {
    0
}

//! > expanded_cairo_code

#[cfg(or(and(a, b), and(k: "a", not(k: "b"))))]
fn f_nested_or_and() -> felt252 {
    0
}

#[cfg(and(or(and(a, b), not(c)), or(not(k: "a"), k: "b")))]
fn f_deep_nested() -> felt252 {
    0
}

#[cfg(or(not(and(a, not(b))), and(k: "a", or(k: "b", c))))]
fn f_complex_evaluation() -> felt252 {
    0
}

//! > expected_diagnostics

//! > ==========================================================================

//! > Test logical operators in config attributes with illegal arguments.

//! > test_runner_name
test_expand_plugin(expect_diagnostics: true)

//! > cfg
["a", "b", ["k", "a"], ["k", "b"]]

//! > cairo_code
#[cfg(not(a, b))]
fn f_invalid_not() -> felt252 {
    0
}

#[cfg(and())]
fn f_invalid_and() -> felt252 {
    0
}

#[cfg(or())]
fn f_invalid_or() -> felt252 {
    0

//! > expanded_cairo_code
#[cfg(not(a, b))]
fn f_invalid_not() -> felt252 {
    0
}

#[cfg(and())]
fn f_invalid_and() -> felt252 {
    0
}

#[cfg(or())]
fn f_invalid_or() -> felt252 {
    0

//! > expected_diagnostics
error: `not` operator expects exactly one argument.
 --> test_src/lib.cairo:1:7
#[cfg(not(a, b))]
      ^^^^^^^^^


error: `and` operator expects at least two arguments.
 --> test_src/lib.cairo:6:7
#[cfg(and())]
      ^^^^^


error: `or` operator expects at least two arguments.
 --> test_src/lib.cairo:11:7
#[cfg(or())]
      ^^^^

//! > ==========================================================================

//! > Test logical operators with unparsable inner arguments are kept, not dropped.

//! > test_runner_name
test_expand_plugin(expect_diagnostics: true)

//! > cfg
["a", "b", ["k", "a"], ["k", "b"]]

//! > cairo_code
#[cfg(or(0, 1))]
const INVALID_OR_ITEMS: felt252 = 0;

#[cfg(and(0, 1))]
const INVALID_AND_ITEMS: felt252 = 0;

#[cfg(and(or(0, 1), 2))]
const INVALID_INNER_ITEMS1: felt252 = 0;

#[cfg(or(2, and(0, 1)))]
const INVALID_INNER_ITEMS2: felt252 = 0;

//! > expanded_cairo_code
#[cfg(or(0, 1))]
const INVALID_OR_ITEMS: felt252 = 0;

#[cfg(and(0, 1))]
const INVALID_AND_ITEMS: felt252 = 0;

#[cfg(and(or(0, 1), 2))]
const INVALID_INNER_ITEMS1: felt252 = 0;

#[cfg(or(2, and(0, 1)))]
const INVALID_INNER_ITEMS2: felt252 = 0;

//! > expected_diagnostics
error: Invalid configuration argument.
 --> test_src/lib.cairo:1:10
#[cfg(or(0, 1))]
         ^


error: Invalid configuration argument.
 --> test_src/lib.cairo:1:13
#[cfg(or(0, 1))]
            ^


error: Invalid configuration argument.
 --> test_src/lib.cairo:4:11
#[cfg(and(0, 1))]
          ^


error: Invalid configuration argument.
 --> test_src/lib.cairo:4:14
#[cfg(and(0, 1))]
             ^


error: Invalid configuration argument.
 --> test_src/lib.cairo:7:14
#[cfg(and(or(0, 1), 2))]
             ^


error: Invalid configuration argument.
 --> test_src/lib.cairo:7:17
#[cfg(and(or(0, 1), 2))]
                ^


error: Invalid configuration argument.
 --> test_src/lib.cairo:7:21
#[cfg(and(or(0, 1), 2))]
                    ^


error: Invalid configuration argument.
 --> test_src/lib.cairo:10:10
#[cfg(or(2, and(0, 1)))]
         ^


error: Invalid configuration argument.
 --> test_src/lib.cairo:10:17
#[cfg(or(2, and(0, 1)))]
                ^


error: Invalid configuration argument.
 --> test_src/lib.cairo:10:20
#[cfg(or(2, and(0, 1)))]
                   ^

//! > ==========================================================================

//! > Test cfg of members does not update visibility.

//! > test_runner_name
test_expand_plugin(expect_diagnostics: false)

//! > cfg
[]

//! > cairo_code
pub trait MyTrait {
    #[cfg(missing_feature)]
    fn removed() -> felt252 {
        0
    }
}

//! > expanded_cairo_code
pub trait MyTrait {
}

//! > expected_diagnostics
