//@needs-asm-support

#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]
#![warn(clippy::map_entry)]

use std::arch::asm;
use std::collections::HashMap;
use std::hash::Hash;

macro_rules! m {
    ($e:expr) => {{ $e }};
}

macro_rules! insert {
    ($map:expr, $key:expr, $val:expr) => {
        $map.insert($key, $val)
    };
}

fn foo() {}

fn hash_map<K: Eq + Hash + Copy, V: Copy>(m: &mut HashMap<K, V>, m2: &mut HashMap<K, V>, k: K, k2: K, v: V, v2: V) {
    // or_insert(v)
    m.entry(k).or_insert(v);

    // semicolon on insert, use or_insert_with(..)
    m.entry(k).or_insert_with(|| {
        //~^ map_entry
        if true {
            v
        } else {
            v2
        }
    });

    // semicolon on if, use or_insert_with(..)
    m.entry(k).or_insert_with(|| {
        //~^ map_entry
        if true {
            v
        } else {
            v2
        }
    });

    // early return, use if let
    if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) {
        //~^ map_entry
        if true {
            e.insert(v);
        } else {
            e.insert(v2);
            return;
        }
    }

    // use or_insert_with(..)
    m.entry(k).or_insert_with(|| {
        //~^ map_entry
        foo();
        v
    });

    // semicolon on insert and match, use or_insert_with(..)
    m.entry(k).or_insert_with(|| {
        //~^ map_entry
        match 0 {
            1 if true => {
                v
            },
            _ => {
                v2
            },
        }
    });

    // one branch doesn't insert, use if let
    if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) {
        //~^ map_entry
        match 0 {
            0 => foo(),
            _ => {
                e.insert(v2);
            },
        };
    }

    // use or_insert_with
    m.entry(k).or_insert_with(|| {
        //~^ map_entry
        foo();
        match 0 {
            0 if false => {
                v
            },
            1 => {
                foo();
                v
            },
            2 | 3 => {
                for _ in 0..2 {
                    foo();
                }
                if true {
                    v
                } else {
                    v2
                }
            },
            _ => {
                v2
            },
        }
    });

    // ok, insert in loop
    if !m.contains_key(&k) {
        for _ in 0..2 {
            m.insert(k, v);
        }
    }

    // macro_expansion test, use or_insert(..)
    m.entry(m!(k)).or_insert_with(|| m!(v));

    // ok, map used before insertion
    if !m.contains_key(&k) {
        let _ = m.len();
        m.insert(k, v);
    }

    // ok, inline asm
    if !m.contains_key(&k) {
        unsafe { asm!("nop") }
        m.insert(k, v);
    }

    // ok, different keys.
    if !m.contains_key(&k) {
        m.insert(k2, v);
    }

    // ok, different maps
    if !m.contains_key(&k) {
        m2.insert(k, v);
    }

    // ok, insert in macro
    if !m.contains_key(&k) {
        insert!(m, k, v);
    }

    // or_insert_with. Partial move of a local declared in the closure is ok.
    m.entry(k).or_insert_with(|| {
        //~^ map_entry
        let x = (String::new(), String::new());
        let _ = x.0;
        v
    });
}

// Issue 10331
// do not suggest a bad expansion because the compiler unrolls the first
// occurrence of the loop
pub fn issue_10331() {
    let mut m = HashMap::new();
    let mut i = 0;
    let mut x = 0;
    while !m.contains_key(&x) {
        m.insert(x, i);
        i += 1;
        x += 1;
    }
}

/// Issue 11935
/// Do not suggest using entries if the map is used inside the `insert` expression.
pub fn issue_11935() {
    let mut counts: HashMap<u64, u64> = HashMap::new();
    if !counts.contains_key(&1) {
        counts.insert(1, 1);
    } else {
        counts.insert(1, counts.get(&1).unwrap() + 1);
    }
}

fn issue12489(map: &mut HashMap<u64, u64>) -> Option<()> {
    if let std::collections::hash_map::Entry::Vacant(e) = map.entry(1) {
        //~^ map_entry
        let Some(1) = Some(2) else {
            return None;
        };
        e.insert(42);
    }
    Some(())
}

mod issue13934 {
    use std::collections::HashMap;

    struct Member {}

    pub struct Foo {
        members: HashMap<u8, Member>,
    }

    impl Foo {
        pub fn should_also_not_cause_lint(&mut self, input: u8) {
            if self.members.contains_key(&input) {
                todo!();
            } else {
                self.other();
                self.members.insert(input, Member {});
            }
        }

        fn other(&self) {}
    }
}

fn issue11976() {
    let mut hashmap = std::collections::HashMap::new();
    if !hashmap.contains_key(&0) {
        let _ = || hashmap.get(&0);
        hashmap.insert(0, 0);
    }
}

mod issue14449 {
    use std::collections::BTreeMap;

    pub struct Meow {
        map: BTreeMap<String, String>,
    }

    impl Meow {
        fn pet(&self, _key: &str, _v: u32) -> u32 {
            42
        }
    }

    pub fn f(meow: &Meow, x: String) {
        if meow.map.contains_key(&x) {
            let _ = meow.pet(&x, 1);
        } else {
            let _ = meow.pet(&x, 0);
        }
    }
}

fn main() {}
