"""
format is
(
    "filename",
    "reason or unique case",
    {
        "expected": "Dictionary of properties extracted from filename",
    },
    bool(xfail: expected failure on the old parser)
)
"""

from __future__ import annotations

import datetime
import importlib.resources
import os
import os.path
import pathlib
from contextlib import nullcontext as does_not_raise

import pytest

datadir = importlib.resources.files(__package__).joinpath("data")
cbz_path = datadir.joinpath("Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz")

names: list[tuple[str, str, dict[str, str | bool], tuple[bool, bool]]] = [
    (
        "De Psy #6 Bonjour l'angoisse!.cbz",
        "'",
        {
            "issue": "6",
            "series": "De Psy",
            "title": "Bonjour l'angoisse!",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
            "archive": "cbz",
        },
        (False, True),
    ),
    (
        "Airfiles #4 The 'Big Show'.cbz",
        "'",
        {
            "issue": "4",
            "series": "Airfiles",
            "title": "The 'Big Show'",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
            "archive": "cbz",
        },
        (False, True),
    ),
    (
        "Conceptions #1 Conceptions I.cbz",
        "&",
        {
            "issue": "1",
            "series": "Conceptions",
            "title": "Conceptions I",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
            "archive": "cbz",
        },
        (False, True),
    ),
    (
        "Series #1 Stop it!.cbz",
        "&",
        {
            "issue": "1",
            "series": "Series",
            "title": "Stop it!",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
            "archive": "cbz",
        },
        (False, True),
    ),
    (
        "Drystan & Esyllt #3",
        "&",
        {
            "issue": "3",
            "series": "Drystan & Esyllt",
            "title": "",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, False),
    ),
    (
        "Michel Vaillant #5 Nr. 13 aan de start",
        "Shortened word followed by a number eg No. 13, Nr. 13",
        {
            "issue": "5",
            "series": "Michel Vaillant",
            "title": "Nr. 13 aan de start",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "Karl May #001 Old Shatterhand.cbr",
        "Month in series",
        {
            "archive": "cbr",
            "issue": "1",
            "series": "Karl May",
            "title": "Old Shatterhand",
            "publisher": "",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "Michel Vaillant #8 De 8ste man",
        "Non english ordinal",
        {
            "issue": "8",
            "series": "Michel Vaillant",
            "title": "De 8ste man",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "Michel Vaillant #13 Mach 1 voor Steve Warson",
        "number in title",
        {
            "issue": "13",
            "series": "Michel Vaillant",
            "title": "Mach 1 voor Steve Warson",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "Michel Vaillant #19 5 Meisjes in de race",
        "number starting title",
        {
            "issue": "19",
            "series": "Michel Vaillant",
            "title": "5 Meisjes in de race",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "Michel Vaillant #34 Steve Warson gaat K.O.",
        "acronym",
        {
            "issue": "34",
            "series": "Michel Vaillant",
            "title": "Steve Warson gaat K.O.",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "Michel Vaillant #40 F.1 in oproer",
        "acronym with numbers",
        {
            "issue": "40",
            "series": "Michel Vaillant",
            "title": "F.1 in oproer",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "Michel Vaillant #42 300 kmu door Parijs",
        "number starting title",
        {
            "issue": "42",
            "series": "Michel Vaillant",
            "title": "300 kmu door Parijs",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "Michel Vaillant #52 F 3000",
        "title ends with number",
        {
            "issue": "52",
            "series": "Michel Vaillant",
            "title": "F 3000",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "Michel Vaillant #66 100.000.000 $ voor Steve Warson",
        "number separator is . and dollarsign after number",
        {
            "issue": "66",
            "series": "Michel Vaillant",
            "title": "100.000.000 $ voor Steve Warson",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "batman #B01 title (DC).cbz",
        "protofolius_issue_number_scheme",
        {
            "archive": "cbz",
            "issue": "B1",
            "series": "batman",
            "title": "title",
            "publisher": "DC",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
            "format": "biography/best of",
        },
        (False, True),
    ),
    (
        "batman #3 title (DC).cbz",
        "publisher in parenthesis",
        {
            "archive": "cbz",
            "issue": "3",
            "series": "batman",
            "title": "title",
            "publisher": "DC",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "batman #3 title DC.cbz",
        "publisher in title",
        {
            "archive": "cbz",
            "issue": "3",
            "series": "batman",
            "title": "title DC",
            "publisher": "DC",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "batman #3 title (DC.cbz",
        "publisher in title",
        {
            "archive": "cbz",
            "issue": "3",
            "series": "batman",
            "title": "title",
            "publisher": "DC",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, True),
    ),
    (
        "ms. Marvel #3.cbz",
        "honorific and publisher in series",
        {
            "archive": "cbz",
            "issue": "3",
            "series": "ms. Marvel",
            "title": "",
            "publisher": "Marvel",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, False),
    ),
    (
        "Dr. Doom And The Masters Of Evil #1 (2009).cbz",
        "honorific and publisher in series",
        {
            "archive": "cbz",
            "issue": "1",
            "series": "Dr. Doom And The Masters Of Evil",
            "title": "",
            "publisher": "",
            "volume": "",
            "year": "2009",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, False),
    ),
    (
        f"action comics #{datetime.datetime.now().year}.cbz",
        "issue number is current year (digits == 4)",
        {
            "archive": "cbz",
            "issue": f"{datetime.datetime.now().year}",
            "series": "action comics",
            "title": "",
            "publisher": "",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, False),
    ),
    (
        "action comics 1024.cbz",
        "issue number is current year (digits == 4)",
        {
            "archive": "cbz",
            "issue": "1024",
            "series": "action comics",
            "title": "",
            "publisher": "",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, False),
    ),
    (
        "Action Comics 1001 (2018).cbz",
        "issue number is current year (digits == 4)",
        {
            "archive": "cbz",
            "issue": "1001",
            "series": "Action Comics",
            "title": "",
            "publisher": "",
            "volume": "",
            "year": "2018",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, False),
    ),
    (
        "january jones #2.cbz",
        "month in series",
        {
            "archive": "cbz",
            "issue": "2",
            "series": "january jones",
            "title": "",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, False),
    ),
    (
        "#52.cbz",
        "issue number only",
        {
            "archive": "cbz",
            "issue": "52",
            "series": "52",
            "title": "",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "alternate": "",
        },
        (False, False),
    ),
    (
        "52 Monster_Island_v1_#2__repaired__c2c.cbz",
        "leading alternate",
        {
            "archive": "cbz",
            "issue": "2",
            "series": "Monster Island",
            "title": "",
            "volume": "1",
            "year": "",
            "remainder": "repaired",
            "issue_count": "",
            "alternate": "52",
            "c2c": True,
        },
        (True, True),
    ),
    (
        "Monster_Island_v1_#2__repaired__c2c.cbz",
        "Example from userguide",
        {
            "archive": "cbz",
            "issue": "2",
            "series": "Monster Island",
            "title": "",
            "volume": "1",
            "year": "",
            "remainder": "repaired",
            "issue_count": "",
            "c2c": True,
        },
        (False, False),
    ),
    (
        "Monster Island v1 #3 (1957) -- The Revenge Of King Klong (noads).cbz",
        "Example from userguide",
        {
            "archive": "cbz",
            "issue": "3",
            "series": "Monster Island",
            "title": "",
            "volume": "1",
            "year": "1957",
            "remainder": "The Revenge Of King Klong (noads)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Foobar-Man Annual #121 - The Wrath of Foobar-Man, Part 1 of 2.cbz",
        "Example from userguide",
        {
            "archive": "cbz",
            "issue": "121",
            "series": "Foobar-Man Annual",
            "title": "The Wrath of Foobar-Man, Part 1 of 2",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
            "annual": True,
        },
        (False, True),
    ),
    (
        "Plastic Man v1 #002 (1942).cbz",
        "Example from userguide",
        {
            "archive": "cbz",
            "issue": "2",
            "series": "Plastic Man",
            "title": "",
            "volume": "1",
            "year": "1942",
            "remainder": "",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Blue Beetle #02.cbr",
        "Example from userguide",
        {
            "archive": "cbr",
            "issue": "2",
            "series": "Blue Beetle",
            "title": "",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Blue Beetle #½.cbr",
        "½",
        {
            "archive": "cbr",
            "issue": "½",
            "series": "Blue Beetle",
            "title": "",
            "volume": "",
            "year": "",
            "remainder": "",
            "issue_count": "",
        },
        (False, True),
    ),
    (
        "Monster Island vol. 2 #2.cbz",
        "Example from userguide",
        {
            "archive": "cbz",
            "issue": "2",
            "series": "Monster Island",
            "title": "",
            "volume": "2",
            "year": "",
            "remainder": "",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Crazy Weird Comics #2 (of 2) (1969).rar",
        "Example from userguide",
        {
            "archive": "rar",
            "issue": "2",
            "series": "Crazy Weird Comics",
            "title": "",
            "volume": "",
            "year": "1969",
            "remainder": "",
            "issue_count": "2",
        },
        (False, False),
    ),
    (
        "Super Strange Yarns (1957) #92 (1969).cbz",
        "Example from userguide",
        {
            "archive": "cbz",
            "issue": "92",
            "series": "Super Strange Yarns",
            "title": "",
            "volume": "1957",
            "year": "1969",
            "remainder": "",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Action Spy Tales v1965 #3.cbr",
        "Example from userguide",
        {
            "archive": "cbr",
            "issue": "3",
            "series": "Action Spy Tales",
            "title": "",
            "volume": "1965",
            "year": "",
            "remainder": "",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        " X-Men-V1-#067.cbr",
        "hyphen separated with hyphen in series",  # only parses correctly because v1 designates the volume
        {
            "archive": "cbr",
            "issue": "67",
            "series": "X-Men",
            "title": "",
            "volume": "1",
            "year": "",
            "remainder": "",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Amazing Spider-Man #078.BEY (2022) (Digital) (Zone-Empire).cbr",
        "number issue with extra",
        {
            "archive": "cbr",
            "issue": "78.BEY",
            "series": "Amazing Spider-Man",
            "title": "",
            "volume": "",
            "year": "2022",
            "remainder": "(Digital) (Zone-Empire)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Angel Wings #02 - Black Widow (2015) (Scanlation) (phillywilly).cbr",
        "title after #issue",
        {
            "archive": "cbr",
            "issue": "2",
            "series": "Angel Wings",
            "title": "Black Widow",
            "volume": "",
            "year": "2015",
            "remainder": "(Scanlation) (phillywilly)",
            "issue_count": "",
        },
        (False, True),
    ),
    (
        "Aquaman - Green Arrow - Deep Target #01 (of 07) (2021) (digital) (Son of Ultron-Empire).cbr",
        "issue count",
        {
            "archive": "cbr",
            "issue": "1",
            "series": "Aquaman - Green Arrow - Deep Target",
            "title": "",
            "volume": "",
            "year": "2021",
            "issue_count": "7",
            "remainder": "(digital) (Son of Ultron-Empire)",
        },
        (False, False),
    ),
    (
        "Aquaman 80th Anniversary 100-Page Super Spectacular (2021) #001 (2021) (Digital) (BlackManta-Empire).cbz",
        "numbers in series",
        {
            "archive": "cbz",
            "issue": "1",
            "series": "Aquaman 80th Anniversary 100-Page Super Spectacular",
            "title": "",
            "volume": "2021",
            "year": "2021",
            "remainder": "(Digital) (BlackManta-Empire)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Avatar - The Last Airbender - The Legend of Korra (FCBD 2021) (Digital) (mv-DCP).cbr",
        "FCBD date",
        {
            "archive": "cbr",
            "issue": "",
            "series": "Avatar - The Last Airbender - The Legend of Korra",
            "title": "",
            "volume": "",
            "year": "2021",
            "remainder": "(Digital) (mv-DCP)",
            "issue_count": "",
            "fcbd": True,
        },
        (True, False),
    ),
    (
        "Avengers By Brian Michael Bendis volume 03 (2013) (Digital) (F2) (Kileko-Empire).cbz",
        "volume without issue",
        {
            "archive": "cbz",
            "issue": "3",
            "series": "Avengers By Brian Michael Bendis",
            "title": "",
            "volume": "3",
            "year": "2013",
            "remainder": "(Digital) (F2) (Kileko-Empire)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Avengers By Brian Michael Bendis v03 (2013) (Digital) (F2) (Kileko-Empire).cbz",
        "volume without issue",
        {
            "archive": "cbz",
            "issue": "3",
            "series": "Avengers By Brian Michael Bendis",
            "title": "",
            "volume": "3",
            "year": "2013",
            "remainder": "(Digital) (F2) (Kileko-Empire)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Batman '89 (2021) (Webrip) (The Last Kryptonian-DCP).cbr",
        "year in title without issue",
        {
            "archive": "cbr",
            "issue": "",
            "series": "Batman '89",
            "title": "",
            "volume": "",
            "year": "2021",
            "remainder": "(Webrip) (The Last Kryptonian-DCP)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Batman_-_Superman_#020_(2021)_(digital)_(NeverAngel-Empire).cbr",
        "underscores",
        {
            "archive": "cbr",
            "issue": "20",
            "series": "Batman - Superman",
            "title": "",
            "volume": "",
            "year": "2021",
            "remainder": "(digital) (NeverAngel-Empire)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Black Widow #009 (2021) (Digital) (Zone-Empire).cbr",
        "standard",
        {
            "archive": "cbr",
            "issue": "9",
            "series": "Black Widow",
            "title": "",
            "volume": "",
            "year": "2021",
            "remainder": "(Digital) (Zone-Empire)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Blade Runner 2029 #006 (2021) (3 covers) (digital) (Son of Ultron-Empire).cbr",
        "year before issue",
        {
            "archive": "cbr",
            "issue": "6",
            "series": "Blade Runner 2029",
            "title": "",
            "volume": "",
            "year": "2021",
            "remainder": "(3 covers) (digital) (Son of Ultron-Empire)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Blade Runner Free Comic Book Day 2021 (2021) (digital-Empire).cbr",
        "FCBD year and (year)",
        {
            "archive": "cbr",
            "issue": "",
            "series": "Blade Runner Free Comic Book Day 2021",
            "title": "",
            "volume": "",
            "year": "2021",
            "remainder": "(digital-Empire)",
            "issue_count": "",
            "fcbd": True,
        },
        (True, False),
    ),
    (
        "Bloodshot Book 03 (2020) (digital) (Son of Ultron-Empire).cbr",
        "book",
        {
            "archive": "cbr",
            "issue": "3",
            "series": "Bloodshot",
            "title": "Book 03",
            "volume": "3",
            "year": "2020",
            "remainder": "(digital) (Son of Ultron-Empire)",
            "issue_count": "",
        },
        (True, False),
    ),
    (
        "book of eli #1 (2020) (digital) (Son of Ultron-Empire).cbr",
        "book",
        {
            "archive": "cbr",
            "issue": "1",
            "series": "book of eli",
            "title": "",
            "volume": "",
            "year": "2020",
            "remainder": "(digital) (Son of Ultron-Empire)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Cyberpunk 2077 - You Have My Word #02 (2021) (digital) (Son of Ultron-Empire).cbr",
        "title",
        {
            "archive": "cbr",
            "issue": "2",
            "series": "Cyberpunk 2077",
            "title": "You Have My Word",
            "volume": "",
            "year": "2021",
            "issue_count": "",
            "remainder": "(digital) (Son of Ultron-Empire)",
        },
        (True, True),
    ),
    (
        "Elephantmen 2259 #008 - Simple Truth 03 (of 06) (2021) (digital) (Son of Ultron-Empire).cbr",
        "volume count",
        {
            "archive": "cbr",
            "issue": "8",
            "series": "Elephantmen 2259",
            "title": "Simple Truth",
            "volume": "3",
            "year": "2021",
            "volume_count": "6",
            "remainder": "(digital) (Son of Ultron-Empire)",
            "issue_count": "",
        },
        (True, True),
    ),
    (
        "Free Comic Book Day - Avengers.Hulk (2021) (2048px) (db).cbz",
        "'.' in name",
        {
            "archive": "cbz",
            "issue": "",
            "series": "Free Comic Book Day - Avengers Hulk",
            "title": "",
            "volume": "",
            "year": "2021",
            "remainder": "(2048px) (db)",
            "issue_count": "",
            "fcbd": True,
        },
        (True, False),
    ),
    (
        "Goblin (2021) (digital) (Son of Ultron-Empire).cbr",
        "no-issue",
        {
            "archive": "cbr",
            "issue": "",
            "series": "Goblin",
            "title": "",
            "volume": "",
            "year": "2021",
            "remainder": "(digital) (Son of Ultron-Empire)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Marvel Previews #002 (January 2022) (Digital-Empire).cbr",
        "(month year)",
        {
            "archive": "cbr",
            "issue": "2",
            "series": "Marvel Previews",
            "title": "",
            "publisher": "Marvel",
            "volume": "",
            "year": "2022",
            "remainder": "(Digital-Empire)",
            "issue_count": "",
        },
        (True, True),
    ),
    (
        "Marvel Two In One V1 #090  c2c (Comixbear-DCP).cbr",
        "volume then issue",
        {
            "archive": "cbr",
            "issue": "90",
            "series": "Marvel Two In One",
            "title": "",
            "publisher": "Marvel",
            "volume": "1",
            "year": "",
            "remainder": "(Comixbear-DCP)",
            "issue_count": "",
            "c2c": True,
        },
        (False, True),
    ),
    (
        "Star Wars - War of the Bounty Hunters - IG-88 (2021) (Digital) (Kileko-Empire).cbz",
        "number ends series, no-issue",
        {
            "archive": "cbz",
            "issue": "",
            "series": "Star Wars - War of the Bounty Hunters - IG-88",
            "title": "",
            "volume": "",
            "year": "2021",
            "remainder": "(Digital) (Kileko-Empire)",
            "issue_count": "",
        },
        (True, False),
    ),
    (
        "Star Wars - War of the Bounty Hunters - IG-88 #1 (2021) (Digital) (Kileko-Empire).cbz",
        "number ends series",
        {
            "archive": "cbz",
            "issue": "1",
            "series": "Star Wars - War of the Bounty Hunters - IG-88",
            "title": "",
            "volume": "",
            "year": "2021",
            "remainder": "(Digital) (Kileko-Empire)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "The Defenders v1 #058 (1978) (digital).cbz",
        "",
        {
            "archive": "cbz",
            "issue": "58",
            "series": "The Defenders",
            "title": "",
            "volume": "1",
            "year": "1978",
            "remainder": "(digital)",
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "The Defenders v1 Annual #01 (1976) (Digital) (Minutemen-Slayer).cbr",
        " v in series",
        {
            "archive": "cbr",
            "issue": "1",
            "series": "The Defenders Annual",
            "title": "",
            "volume": "1",
            "year": "1976",
            "remainder": "(Digital) (Minutemen-Slayer)",
            "issue_count": "",
            "annual": True,
        },
        (True, True),
    ),
    (
        "The Magic Order 2 #06 (2022) (Digital) (Zone-Empire)[__913302__].cbz",
        "ending id",
        {
            "archive": "cbz",
            "issue": "6",
            "series": "The Magic Order 2",
            "title": "",
            "volume": "",
            "year": "2022",
            "remainder": "(Digital) (Zone-Empire)[913302]",  # Don't really care about double underscores
            "issue_count": "",
        },
        (False, False),
    ),
    (
        "Wonder Woman #001 Wonder Woman Day Special Edition (2021) (digital-Empire).cbr",
        "issue separates title",
        {
            "archive": "cbr",
            "issue": "1",
            "series": "Wonder Woman",
            "title": "Wonder Woman Day Special Edition",
            "volume": "",
            "year": "2021",
            "remainder": "(digital-Empire)",
            "issue_count": "",
        },
        (False, True),
    ),
    (
        "Wonder Woman #49 DC Sep-Oct 1951 digital [downsized, lightened, 4 missing story pages restored] (Shadowcat-Empire).cbz",
        "date-range, no paren, braces",
        {
            "archive": "cbz",
            "issue": "49",
            "series": "Wonder Woman",
            "title": "digital",  # Don't have a way to get rid of this
            "publisher": "DC",
            "volume": "",
            "year": "1951",
            "remainder": "[downsized, lightened, 4 missing story pages restored] (Shadowcat-Empire)",
            "issue_count": "",
        },
        (True, True),
    ),
    (
        "X-Men, 2021-08-04 (#02) (digital) (Glorith-HD).cbz",
        "full-date, issue in parenthesis",
        {
            "archive": "cbz",
            "issue": "2",
            "series": "X-Men",
            "title": "",
            "volume": "",
            "year": "2021",
            "remainder": "(digital) (Glorith-HD)",
            "issue_count": "",
        },
        (True, True),
    ),
    (
        "Cory Doctorow's Futuristic Tales of the Here and Now: Anda's Game #001 (2007).cbz",
        "title",
        {
            "archive": "cbz",
            "issue": "1",
            "series": "Cory Doctorow's Futuristic Tales of the Here and Now",
            "title": "Anda's Game",
            "volume": "",
            "year": "2007",
            "remainder": "",
            "issue_count": "",
        },
        (True, True),
    ),
    (
        "Cory Doctorow's Futuristic Tales of the Here and Now $1$2 3 #0.0.1 (2007).cbz",
        "$",
        {
            "archive": "cbz",
            "issue": "0.1",
            "series": "Cory Doctorow's Futuristic Tales of the Here and Now $1 $2 3",
            "title": "",
            "volume": "",
            "year": "2007",
            "remainder": "",
            "issue_count": "",
        },
        (True, True),
    ),
]

oldfnames = []
newfnames = []
for p in names:
    filename, reason, info, xfail = p
    filenameinfo = dict(
        alternate="",
        annual=False,
        archive="",
        c2c=False,
        fcbd=False,
        issue="",
        issue_count="",
        publisher="",
        remainder="",
        series="",
        title="",
        volume="",
        volume_count="",
        year="",
        format="",
    )
    filenameinfo.update(info)
    nxfail = xfail[0]
    newfnames.append(pytest.param(filename, reason, filenameinfo.copy(), nxfail))
    oldfnames.append(
        pytest.param(
            filename,
            reason,
            filenameinfo.copy(),
            nxfail,
            marks=pytest.mark.xfail(condition=nxfail, reason="old parser"),
        )
    )
    if "#" in filename:
        filename = filename.replace("#", "")
        nxfail = xfail[1]
        if reason in ("protofolius_issue_number_scheme", "number starting title"):
            newfnames.append(
                pytest.param(
                    filename,
                    reason,
                    filenameinfo.copy(),
                    nxfail,
                    marks=pytest.mark.xfail(condition=nxfail, reason=reason),
                )
            )
        else:
            newfnames.append(pytest.param(filename, reason, filenameinfo.copy(), nxfail))
        oldfnames.append(
            pytest.param(
                filename,
                reason,
                filenameinfo.copy(),
                nxfail,
                marks=pytest.mark.xfail(condition=nxfail, reason="old parser"),
            )
        )

file_renames = [
    (
        "{series} #{issue} - {title} ({year}) ({price!c})",  # conversion on None
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
        does_not_raise(),
    ),
    (
        "{country[0]} {price} {year}",  # Indexing a None value
        False,
        False,
        "universal",
        "2007.cbz",
        does_not_raise(),
    ),
    (
        "{series!c} {price} {year}",  # Capitalize
        False,
        False,
        "universal",
        "Cory doctorow's futuristic tales of the here and now 2007.cbz",
        does_not_raise(),
    ),
    (
        "{series!t} {price} {year}",  # Title Case
        False,
        False,
        "universal",
        "Cory Doctorow'S Futuristic Tales Of The Here And Now 2007.cbz",
        does_not_raise(),
    ),
    (
        "{series!S} {price} {year}",  # Swap Case
        False,
        False,
        "universal",
        "cORY dOCTOROW'S fUTURISTIC tALES OF THE hERE AND nOW 2007.cbz",
        does_not_raise(),
    ),
    (
        "{title!l} {price} {year}",  # Lowercase
        False,
        False,
        "universal",
        "anda's game 2007.cbz",
        does_not_raise(),
    ),
    (
        "{title!u} {price} {year}",  # Upper Case
        False,
        False,
        "universal",
        "ANDA'S GAME 2007.cbz",
        does_not_raise(),
    ),
    (
        "{title} {price} {year+}",  # Empty alternate value
        False,
        False,
        "universal",
        "Anda's Game.cbz",
        does_not_raise(),
    ),
    (
        "{title} {price} {year+year!u}",  # Alternate value Upper Case
        False,
        False,
        "universal",
        "Anda's Game YEAR.cbz",
        does_not_raise(),
    ),
    (
        "{title} {price} {year+year}",  # Alternate Value
        False,
        False,
        "universal",
        "Anda's Game year.cbz",
        does_not_raise(),
    ),
    (
        "{title} {price-0} {year}",  # Default value
        False,
        False,
        "universal",
        "Anda's Game 0 2007.cbz",
        does_not_raise(),
    ),
    (
        "{title} {price+0} {year}",  # Alternate Value
        False,
        False,
        "universal",
        "Anda's Game 2007.cbz",
        does_not_raise(),
    ),
    (
        "{series} #{issue} - {title} ({year}) ({price})",  # price should be none
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} #{issue} - {title} {volume:02} ({year})",  # Ensure format specifier works
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game 01 (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} #{issue} - {title} ({year})({price})",  # price should be none, test no  space between ')('
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} #{issue} - {title} ({year})  ({price})",  # price should be none, test double space ')  ('
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} #{issue} - {title} ({year})",
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
        does_not_raise(),
    ),
    (
        "{title} {web_link}",  # Ensure colon is replaced in metadata
        False,
        False,
        "universal",
        "Anda's Game https---comicvine.gamespot.com-cory-doctorows-futuristic-tales-of-the-here-and-no-4000-140529-.cbz",
        does_not_raise(),
    ),
    (
        "{title} {web_link}",  # Ensure slashes are replaced in metadata on linux/macos
        False,
        False,
        "Linux",
        "Anda's Game https:--comicvine.gamespot.com-cory-doctorows-futuristic-tales-of-the-here-and-no-4000-140529-.cbz",
        does_not_raise(),
    ),
    (
        "{title} {web_links!j}",  # Test that join forces str conversion
        False,
        False,
        "Linux",
        "Anda's Game https:--comicvine.gamespot.com-cory-doctorows-futuristic-tales-of-the-here-and-no-4000-140529-.cbz",
        does_not_raise(),
    ),
    (
        "{series}:{title} #{issue} ({year})",  # on windows the ':' is replaced
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now-Anda's Game #001 (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series}: {title} #{issue} ({year})",  # on windows the ':' is replaced
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game #001 (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series}: {title} #{issue} ({year})",  # on linux the ':' is preserved
        False,
        False,
        "Linux",
        "Cory Doctorow's Futuristic Tales of the Here and Now: Anda's Game #001 (2007).cbz",
        does_not_raise(),
    ),
    (
        "{publisher}/  {series} #{issue} - {title} ({year})",  # leading whitespace is removed when moving
        True,
        False,
        "universal",
        "IDW Publishing/Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
        does_not_raise(),
    ),
    (
        "{publisher}/  {series} #{issue} - {title} ({year})",  # leading whitespace is removed when only renaming
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
        does_not_raise(),
    ),
    (
        r"{publisher}\  {series} #{issue} - {title} ({year})",  # backslashes separate directories
        False,
        False,
        "Linux",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} #  {issue} - {title} ({year})",  # double spaces are reduced to one
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now # 001 - Anda's Game (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} #{issue} - {locations!j} ({year})",
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 - lonely cottage (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} #{issue} - {title} - {WriteR}, {EDITOR} ({year})",  # fields are case in-sensitive
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game - Dara Naraghi, Ted Adams (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} v{price} #{issue} ({year})",  # Remove previous text if value is ""
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} {price} #{issue} ({year})",  # Ensure that a single space remains
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now #001 (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} - {title}{price} #{issue} ({year})",  # Ensure removal before None values only impacts literal text
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game #001 (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} - {title} {test} #{issue} ({year})",  # Test non-existent key
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game {test} #001 (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} - {title} #{issue} ({year} {price})",  # Test null value in parenthesis with a non-null value
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game #001 (2007).cbz",
        does_not_raise(),
    ),
    (
        "{series} - {title} #{issue} (of {price})",  # null value with literal text in parenthesis
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game #001.cbz",
        does_not_raise(),
    ),
    (
        "{series} - {title} {1} #{issue} ({year})",  # Test numeric key
        False,
        False,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game {test} #001 (2007).cbz",
        pytest.raises(ValueError),
    ),
    (
        "{series} - {title} #{issue} ({year})",
        False,
        True,
        "universal",
        "Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game #001 (2007)/cory doctorow #1.cbz",
        does_not_raise(),
    ),
]

folder_names = [
    (None, lambda: pathlib.Path(str(cbz_path)).parent.absolute()),
    ("", lambda: pathlib.Path(os.getcwd())),
    ("test", lambda: (pathlib.Path(os.getcwd()) / "test")),
    (pathlib.Path(os.getcwd()) / "test", lambda: pathlib.Path(os.getcwd()) / "test"),
]
