from nameparser.config._invariants import assert_normalized

FIRST_NAME_TITLES = {
    'aunt',
    'auntie',
    'brother',
    'dame',
    'father',
    'king',
    'maid',
    'master',
    'mother',
    'pope',
    'queen',
    'sir',
    'sister',
    'uncle',
    'sheikh',
    'sheik',
    'shaik',
    'shayk',
    'shaykh',
    'shaikh',
    'cheikh',
    'shekh',
    # #269: Arabic -- "الشيخ" ("the sheikh") is the native-script form of
    # the transliterated sheikh/sheik/... cluster above; same
    # single-first-name-follows convention ("Sheikh Mohammed").
    'الشيخ',
    # #269 follow-up: Arabic honorifics precede the GIVEN name, so all
    # belong here rather than in plain TITLES. Article forms are never
    # given names; the bare doctor/professor/engineer forms are not
    # used as given names either. Deferred under the collision rule
    # (like мл/ст in suffixes.py): bare سيد (Sayyid is a common given
    # name), bare شيخ (Shaikha is a common female given name), أمير
    # and سلطان (Amir/Sultan, common given names), and the 'د.'
    # abbreviation -- edge-period normalization would leave bare 'د',
    # which swallows single-letter initials (the bare-κ trap above).
    'الدكتور',     # "the doctor" (m)
    'الدكتورة',    # "the doctor" (f)
    'دكتور',       # doctor (m), article-less
    'دكتورة',      # doctor (f), article-less
    'الأستاذ',     # "the professor"/Mr. honorific (m)
    'الأستاذة',    # professor/Mrs. honorific (f)
    'أستاذ',       # professor (m), article-less
    'أستاذة',      # professor (f), article-less
    'الحاج',       # hajj honorific (m)
    'الحاجة',      # hajj honorific (f)
    'الشيخة',      # female counterpart of الشيخ
    'مهندس',       # engineer (a genuine title in Egyptian usage)
}
"""
When these titles appear with a single other name, that name is a first name, e.g.
"Sir John", "Sister Mary", "Queen Elizabeth".
"""

#: **Cannot include things that could also be first names**, e.g. "dean".
#: Many of these from wikipedia: https://en.wikipedia.org/wiki/Title.
#: The parser recognizes chains of these including conjunctions allowing 
#: recognition titles like "Deputy Secretary of State".
TITLES = FIRST_NAME_TITLES | {
    "attaché",
    "chargé",
    "d'affaires",
    "king's",
    "marchioness",
    "marquess",
    "marquis",
    "marquise",
    "queen's",
    '10th',
    '1lt',
    '1sgt',
    '1st',
    '1stlt',
    '1stsgt',
    '2lt',
    '2nd',
    '2ndlt',
    '3rd',
    '4th',
    '5th',
    '6th',
    '7th',
    '8th',
    '9th',
    'a1c',
    'ab',
    'abbess',
    'abbot',
    'abolitionist',
    'academic',
    'acolyte',
    'activist',
    'actor',
    'actress',
    'adept',
    'adjutant',
    'adm',
    'admiral',
    'advertising',
    'adviser',
    'advocate',
    'air',
    'akhoond',
    'alderman',
    'almoner',
    'ambassador',
    'amn',
    'analytics',
    'anarchist',
    'animator',
    'anthropologist',
    'appellate',
    'apprentice',
    'arbitrator',
    'archbishop',
    'archdeacon',
    'archdruid',
    'archduchess',
    'archduke',
    'archeologist',
    'architect',
    'arhat',
    'army',
    'arranger',
    'assistant',
    'assoc',
    'associate',
    'asst',
    'astronomer',
    'attache',
    'attorney',
    'author',
    'award-winning',
    'ayatollah',
    'baba',
    'bailiff',
    'ballet',
    'bandleader',
    'banker',
    'banner',
    'bard',
    'baron',
    'baroness',
    'barrister',
    'baseball',
    'bearer',
    'behavioral',
    'bench',
    'bg',
    'bgen',
    'biblical',
    'bibliographer',
    'biochemist',
    'biographer',
    'biologist',
    'bishop',
    'blessed',
    'blogger',
    'blues',
    'bodhisattva',
    'bookseller',
    'botanist',
    'bp',
    'brigadier',
    'briggen',
    'british',
    'broadcaster',
    'buddha',
    'burgess',
    'burlesque',
    'business',
    'businessman',
    'businesswoman',
    'bwana',
    'canon',
    'capt',
    'captain',
    'cardinal',
    'cartographer',
    'cartoonist',
    'catholicos',
    'ccmsgt',
    'cdr',
    'celebrity',
    'ceo',
    'cfo',
    'chair',
    'chairs',
    'chancellor',
    'chaplain',
    'charge',  # unaccented 'chargé', like attaché/'attache'
    'chef',
    'chemist',
    'chief',
    'chieftain',
    'choreographer',
    'civil',
    'classical',
    'clergyman',
    'clerk',
    'cmsaf',
    'cmsgt',
    'co-chair',
    'co-chairs',
    'co-founder',
    'coach',
    'col',
    'collector',
    'colonel',
    'comedian',
    'comedienne',
    'comic',
    'commander',
    'commander-in-chief',
    'commodore',
    'composer',
    'compositeur',
    'comptroller',
    'computer',
    'comtesse',
    'conductor',
    'consultant',
    'controller',
    'corporal',
    'corporate',
    'correspondent',
    'councillor',
    'counselor',
    'count',
    'countess',
    'courtier',
    'cpl',
    'cpo',
    'cpt',
    'credit',
    'criminal',
    'criminologist',
    'critic',
    'csm',
    'curator',
    'customs',
    'cwo-2',
    'cwo-3',
    'cwo-4',
    'cwo-5',
    'cwo2',
    'cwo3',
    'cwo4',
    'cwo5',
    'cyclist',
    'dancer',
    'dcn',
    'deacon',
    'delegate',
    'deputy',
    'designated',
    'designer',
    'detective',
    'developer',
    'dhr',
    'dipl.-ing',
    'diplomat',
    'dir',
    'director',
    'discovery',
    'dissident',
    'district',
    'division',
    'do',
    'docent',
    'docket',
    'doctor',
    'doyen',
    'dpty',
    'dr',
    'dra',
    'dramatist',
    'druid',
    'drummer',
    'duchesse',
    # 'duke', # a common first name
    'dutchess',
    'ecologist',
    'economist',
    'editor',
    'edler',
    'edmi',
    'edohen',
    'educator',
    'effendi',
    'ekegbian',
    'elerunwon',
    'eminence',
    'emperor',
    'empress',
    'engineer',
    'english',
    'ens',
    'entertainer',
    'entrepreneur',
    'envoy',
    'erzbischof',
    'essayist',
    'evangelist',
    'excellency',
    'excellent',
    'exec',
    'executive',
    'expert',
    'fadm',
    'family',
    'federal',
    'fh-prof',
    'field',
    'film',
    'financial',
    'first',
    'flag',
    'flying',
    'foreign',
    'forester',
    'founder',
    'fr',
    'frau',
    'fräulein',
    'freifrau',
    'freiherr',
    'friar',
    'frk',
    'frøken',
    'fru',
    'fürst',
    'fürsterzbischof',
    'gaf',
    'gen',
    'general',
    'generalissimo',
    'gentiluomo',
    'giani',
    'goodman',
    'goodwife',
    'governor',
    'graf',
    'gräfin',
    'grand',
    'großfürst',
    'group',
    'guitarist',
    'guru',
    'gyani',
    'gysgt',
    'hajji',
    'headman',
    'heir',
    'heiress',
    'her',
    'hereditary',
    'heren',
    'herr',
    'herzog',
    'herren',
    'herrn',
    'high',
    'highness',
    'his',
    'historian',
    'historicus',
    'historien',
    'holiness',
    'hon', # sorry Hon Solo, but judges seem more common.
    'honorable',
    'honourable',
    'host',
    'hr',
    'illustrator',
    'imam',
    'industrialist',
    'information',
    'instructor',
    'intelligence',
    'intendant',
    'inventor',
    'investigator',
    'investor',
    'journalist',
    'journeyman',
    'jr',
    'judge',
    'judicial',
    'junior',
    'jurist',
    'keyboardist',
    'kingdom',
    'knowledge',
    'lady',
    'lama',
    'lamido',
    'law',
    'lawyer',
    'lcdr',
    'lcpl',
    'leader',
    'lecturer',
    'legal',
    'librarian',
    'lieutenant',
    'linguist',
    'literary',
    'lord',
    'lt',
    'ltc',
    'ltcol',
    'ltg',
    'ltgen',
    'ltjg',
    'lyricist',
    'madam',
    'madame',
    'mademoiselle',
    'mag',
    'mag-judge',
    'mag/judge',
    'magistrate',
    'magistrate-judge',
    'magnate',
    'maharajah',
    'maharani',
    'mahdi',
    'maj',
    'majesty',
    'majgen',
    'manager',
    'marcher',
    'marchess',
    'marketing',
    'marquis',
    'mathematician',
    'mathematics',
    'matriarch',
    'mayor',
    'mcpo',
    'mcpoc',
    'mcpon',
    'md',
    'me',
    'member',
    'memoirist',
    'merchant',
    'met',
    'metropolitan',
    'mevr',
    'mevrouw',
    'mevrouwe',
    'mg',
    'mgr',
    'mgysgt',
    'military',
    'minister',
    'miss',
    'misses',
    'missionary',
    'mister',
    'mlle',
    'mme',
    'mobster',
    'model',
    'monk',
    'monseigneur',
    'monsieur',
    'monsignor',
    'most',
    'mountaineer',
    'mpco-cg',
    'mr',
    'mrs',
    'ms',
    'msg',
    'msgt',
    'mufti',
    'mullah',
    'municipal',
    'murshid',
    'musician',
    'musicologist',
    'mx',
    'mystery',
    'nanny',
    'narrator',
    'national',
    'naturalist',
    'navy',
    'neuroscientist',
    'novelist',
    'nurse',
    'obstetritian',
    'officer',
    'opera',
    'operating',
    'ornithologist',
    'painter',
    'paleontologist',
    'pastor',
    'patriarch',
    'pd',
    'pediatrician',
    'personality',
    'petty',
    'pfc',
    'pharaoh',
    'phd',
    'philantropist',
    'philosopher',
    'photographer',
    'physician',
    'physicist',
    'pianist',
    'pilot',
    'pioneer',
    'pir',
    'player',
    'playwright',
    'po1',
    'po2',
    'po3',
    'poet',
    'police',
    'political',
    'politician',
    'prefect',
    'prelate',
    'premier',
    'pres',
    'presbyter',
    'president',
    'presiding',
    'priest',
    'priestess',
    'primate',
    'prime',
    'prin',
    'prince',
    'princess',
    'principal',
    'printer',
    'printmaker',
    'prinz',
    'priv.-doz',
    'prior',
    'private',
    'pro',
    'producer',
    'prof',
    'professor',
    'provost',
    'pslc',
    'psychiatrist',
    'psychologist',
    'publisher',
    'pursuivant',
    'pv2',
    'pvt',
    'ra',
    'rabbi',
    'radio',
    'radm',
    'rangatira',
    'ranger',
    'rdml',
    'rear',
    'rebbe',
    'reichsgraf',
    'registrar',
    'rep',
    'representative',
    'researcher',
    'resident',
    'rev',
    'revenue',
    'reverend',
    'right',
    'risk',
    'ritter',
    'rock',
    'royal',
    'rt',
    'sa',
    'sailor',
    'saint',
    'sainte',
    'saoshyant',
    'satirist',
    'scholar',
    'schoolmaster',
    'scientist',
    'scpo',
    'screenwriter',
    'se',
    'secretary',
    'security',
    'seigneur',
    'senator',
    'senhor',
    'senhora',
    'senhorita',
    'senior',
    'señor',
    'señora',
    'señores',
    'señorita',
    'señoritas',
    'senior-judge',
    'sergeant',
    'servant',
    'sfc',
    'sgm',
    'sgt',
    'sgtmaj',
    'sgtmajmc',
    'shehu',
    'sheikh',
    'sheriff',
    'siddha',
    'signor',
    'signora',
    'signore',
    'signorina',
    'singer',
    'singer-songwriter',
    'sma',
    'smsgt',
    'sn',
    'soccer',
    'social',
    'sociologist',
    'software',
    'soldier',
    'solicitor',
    'soprano',
    'spc',
    'speaker',
    'special',
    'sr',
    'sra',
    'srta',
    'srtas',
    'sres',
    'ssg',
    'ssgt',
    'st',
    'staff',
    'state',
    'states',
    'strategy',
    'subaltern',
    'subedar',
    'suffragist',
    'sultan',
    'sultana',
    'superior',
    'supreme',
    'surgeon',
    'swami',
    'swordbearer',
    'sysselmann',
    'tax',
    'teacher',
    'technical',
    'technologist',
    'television',
    'tenor',
    'theater',
    'theatre',
    'theologian',
    'theorist',
    'timi',
    'tirthankar',
    'translator',
    'travel',
    'treasurer',
    'tsar',
    'tsarina',
    'tsgt',
    'uk',
    'united',
    'univ.prof',
    'us',
    'vadm',
    'vardapet',
    'vc',
    'venerable',
    'verderer',
    'vicar',
    'vice',
    'viscount',
    'vizier',
    'vocalist',
    'voice',
    'vrouwe',
    'warden',
    'warrant',
    'wing',
    'wm',
    'wp',
    'wo-1',
    'wo1',
    'wo2',
    'wo3',
    'wo4',
    'wo5',
    'woodman',
    'writer',
    'zoologist',

    # #269: Cyrillic (ru/uk) -- mr/mrs/dr/prof/academician/pan(i)
    # honorifics, same title-then-family convention as 'mr'/'dr'/'prof'
    # above (not FIRST_NAME_TITLES: "г-н Петров" families the surname
    # just like "Mr. Smith" does).
    'г-н',
    'г-жа',
    'д-р',
    'проф',
    'акад',
    'пан',
    'пані',

    # #269: Greek -- kyria/kyrios(abbr)/doctor/professor abbreviations;
    # same plain-title convention as above.
    # #269: bare κ deferred -- collides with the initial+surname shape
    # ('Κ. Παπαδόπουλος' would parse as title 'Κ.' with an empty given;
    # _normalize strips the edge period, so the entry matches the
    # initial). Latin TITLES deliberately has no bare single-letter
    # entries for the same reason.
    'κα',
    'κος',
    'δρ',
    'καθ',

    # #269: Hebrew -- "מר" ("Mr."), plain title like its Latin analog.
    # Geresh/gershayim forms of "doctor"/"Mrs." -- both the ASCII-quote
    # spelling ('ד"ר', "גב'") and the typographic Unicode spelling
    # ('ד״ר' U+05F4 gershayim, 'גב׳' U+05F3 geresh) ship: probed live
    # against extract_delimited's _open_ok/_close_ok boundary rules
    # (2026-07-17) -- the quote chars sit mid-word (no preceding
    # whitespace before the internal quote and, for the closing "'" one,
    # no following boundary), so both fail the open/close boundary test
    # and are left untouched as literal text. Extraction is provably
    # inert on these two ASCII spellings; no delimiter-interaction risk.
    'מר',
    'ד"ר',
    "גב'",
    'ד״ר',
    'גב׳',
    # #269 follow-up: the rest of the common Israeli honorifics, same
    # plain-title bucket (family follows) and the same dual geresh/
    # gershayim spelling rule as above. Deferred under the collision
    # rule: bare 'רב' (also the ordinary word "many"). The 'בר'
    # particle deferral is recorded in prefixes.py with the other
    # particle decisions.
    'גברת',       # Mrs./Ms., full form
    "פרופ'",      # professor abbreviation, ASCII apostrophe
    'פרופ׳',      # professor abbreviation, U+05F3 geresh
    'פרופסור',    # professor, full form
    'עו"ד',       # advocate/lawyer, ASCII quote
    'עו״ד',       # advocate/lawyer, U+05F4 gershayim
    'הרב',        # "the rabbi" (article form; bare רב deferred)

    # #269 follow-up: Devanagari (hi/mr). NO Latin twins on purpose:
    # transliterated sri/shri collide with real given names (Sri
    # Mulyani); the native-script forms cannot. "डॉ." matches via the
    # edge-period normalization, like Latin "Dr.".
    'श्री',        # Shri (Mr.)
    'श्रीमती',     # Shrimati (Mrs.)
    'डॉ',         # Dr. abbreviation
}


# Guard the invariants at import time, so a bad edit fails here instead of
# drifting silently until a test happens to catch it (see prefixes.py).
# The subset rule holds by construction today -- TITLES is defined as
# FIRST_NAME_TITLES | {...} -- so this pins it against a future edit that
# makes TITLES a standalone set. Lexicon enforces the same rule on
# caller-supplied vocabulary; `assert` is stripped under `python -O`.
assert FIRST_NAME_TITLES <= TITLES, \
    "FIRST_NAME_TITLES must stay a subset of TITLES"
# TITLES covers FIRST_NAME_TITLES, by the subset assert above.
assert_normalized("TITLES", TITLES)
