use nom::{
    IResult, Parser as _,
    bytes::complete::{tag, take_till1},
    character::complete::{char, space0},
    combinator::opt,
    sequence::{delimited, preceded},
};

use crate::ast::Wikilink;

pub(super) fn wikilink<'a>() -> impl FnMut(&'a str) -> IResult<&'a str, Wikilink> {
    move |input: &'a str| {
        let (input, (link, target, name)) = delimited(
            (tag("[["), space0),
            (
                take_till1(|c| matches!(c, '#' | '|' | ']')),
                opt(preceded(char('#'), take_till1(|c| matches!(c, '|' | ']')))),
                opt(preceded(char('|'), take_till1(|c| matches!(c, ']')))),
            ),
            (space0, tag("]]")),
        )
        .parse(input)?;

        let tag = Wikilink {
            link: link.to_owned(),
            target: target.map(ToOwned::to_owned),
            name: name.map(ToOwned::to_owned),
        };

        Ok((input, tag))
    }
}
