# Path: athlib/codes.py
# PAT_THROWS = re.compile(
#                         (
#                         r"^(?:"
#                         r"[sS]?[dD][tT](?P<dtnum>%s|)|"
#                         r"[sS]?[jJ][tT](?P<jtnum>[45678]00\s*g?|)|"
#                         r"[hH][tT](?P<htnum>%s|)|"
#                         r"[sS][pP](?P<spnum>%s|)|"
#                         r"[wW][tT](?P<wtnum>\d?%s|)|"
#                         r"[sS][sW][tT](?P<swtnum>%s|)|"
#                         r"[sS]?[bB][tT](?P<btnum>%s|)|"
#                         r"[sS][tT](?P<stnum>%s|)|"
#                         r"[gG][dD][tT](?P<gdtnum>%s|)|"
#                         r"[oO][tT](?P<otnum>\d+\s*g?|)|"
#                         r"[tT][aA][rR][tT]|"  # weight not relevant
#                         r"[cC][hH][tT]|"
#                         r"[oO][hH][tT]|"                         
#                         r"[Hh][1-9]|"
#                         r"[Ll][1-9]"
#                         ")$"
#                         ) % (_, _, _, _, _, _, _, _),
#                         )
# 
# PAT_JUMPS = re.compile(_orjoin(PAT_VERTICAL_JUMPS,PAT_HORIZONTAL_JUMPS))
# 
# PAT_RELAYS = re.compile(r"^(?:(\d{1,2})[xX](\d{2,5}[hH]?|[rR][eE][lL][aA][yY]))$") # 4x100, 4x400, 4xReLAy, 12x200H
# 
# PAT_HURDLES = re.compile(r"^(?:(\d{2,4})(?:%s))$" % re.sub(r'\(\?P<[^>]*>','(',_)) # 80H, 110H, 400H
# 
# PAT_TRACK = re.compile(r"^(?:(?:(?P<meters>\d+)\s*(?P<msfx>%s|[yY]|[wW])?)|[sS][cC]|[2345][mM][tT]|[lL][hH]|[sS][hH])$" % _)
# 
# PAT_LEADING_DIGITS = re.compile(r"^\d+")
# 
# PAT_LEADING_FLOAT = re.compile(r"^\d+\.\d*")
# 
# PAT_PERF = re.compile(r"^(\d{1,2}:)?(\d{1,2}:)?(\d{1,2})(\.?\d+)?$")
# 
# PAT_LONG_SECONDS = re.compile(r"^\d{3,6}(\.?\d+)?$")
# 
# PAT_EVENT_CODE=re.compile(_orjoin(PAT_MULTI,PAT_RUN,
#                 PAT_FIELD,PAT_RELAYS,PAT_HURDLES,PAT_RACES_FOR_DISTANCE, 
#                 PAT_HIGHSCORING_EVENT, PAT_LOWSCORING_EVENT))
# 
# FIELD_EVENTS = JUMPS + THROWS
# 
# MULTI_EVENTS = (
#     # Greek prefixes for 2..12 events, and for 20.
#     "BI", "TRI", "QUAD", "PEN", "HEX", "HEP", "OCT", "ENN", "DEC",
#     "HEN", "DOD", "ICO",
# 
#     "PENI",  # Indoor Pentathlon, not sure if we should keep this
#     "PENWT",  # Weights Pentathlon - defines what events go in it.
# )
# 
# CUSTOM_EVENTS = CUSTOM_HIGHSCORING_EVENTS + CUSTOM_LOWSCORING_EVENTS
# 
# FIELD_SORT_ORDER = [
#         "HJ", "SHJ",
#         "PV", 
#         "LJ", "SLJ",
#         "TJ", "STJ",
#         "SP", "DT", "HT", "JT", 
#         "ST", "GDT", "BT", "WT", "SWT", "OT", "TART", "OHT", "CHT", "SDT", "SJT", "SBT",
#         "H1", "H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9",   #Custom Events
#         "L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8", "L9",   #Custom Events
#         ]
# 
# PAT_RACES_FOR_DISTANCE = re.compile(r"^(?:(?P<dhours>\d\d?)([hH](?:[rR]|[wW]))|[tT](?P<dmins>\d+))$")


import sys, os, json
import jsonschema
import jsonschema.validators
import builtins
from collections import OrderedDict
from jsonschema.validators import RefResolver as OriginalResolver
from jsonschema.exceptions import SchemaError, ValidationError
from typing import Any, Union, Dict, Optional, Type, Tuple, Match, List, TypeVar
from .codes import PAT_THROWS, PAT_JUMPS, PAT_RELAYS, PAT_HURDLES, PAT_TRACK, \
    PAT_LEADING_DIGITS, PAT_LEADING_FLOAT, PAT_PERF, PAT_LONG_SECONDS, PAT_EVENT_CODE, \
    FIELD_EVENTS, MULTI_EVENTS, CUSTOM_EVENTS, FIELD_SORT_ORDER, PAT_RACES_FOR_DISTANCE
    if m:
        distance = int(m.group(1))
        return 1, distance, discipline

    # anything else sorts to end
    return 6, 0, discipline

def text_discipline_sort_key(discipline: str) -> str:
    "Return a text version of the event_sort_key"
    return "%d_%05d_%s" % discipline_sort_key(discipline)

T = TypeVar('T')

def sort_by_discipline(stuff: List[T], attr: str = "discipline") -> List[T]:
    "Sort dicts or objects into the normal athletics order"

    sorter = []
    for thing in stuff:
        if isinstance(thing, dict):
            disc = thing.get(attr, None)
        else:
            # assume object
            disc = getattr(thing, attr, None)
        priority = discipline_sort_key(disc)
        sorter.append((priority, thing))

    sorter.sort(key=lambda x: x[0])
    return [thing for (priority, thing) in sorter]

def check_event_code(c: str) -> Optional[Match[str]]:

# Path: athlib/codes.py
# PAT_THROWS = re.compile(
#                         (
#                         r"^(?:"
#                         r"[sS]?[dD][tT](?P<dtnum>%s|)|"
#                         r"[sS]?[jJ][tT](?P<jtnum>[45678]00\s*g?|)|"
#                         r"[hH][tT](?P<htnum>%s|)|"
#                         r"[sS][pP](?P<spnum>%s|)|"
#                         r"[wW][tT](?P<wtnum>\d?%s|)|"
#                         r"[sS][sW][tT](?P<swtnum>%s|)|"
#                         r"[sS]?[bB][tT](?P<btnum>%s|)|"
#                         r"[sS][tT](?P<stnum>%s|)|"
#                         r"[gG][dD][tT](?P<gdtnum>%s|)|"
#                         r"[oO][tT](?P<otnum>\d+\s*g?|)|"
#                         r"[tT][aA][rR][tT]|"  # weight not relevant
#                         r"[cC][hH][tT]|"
#                         r"[oO][hH][tT]|"                         
#                         r"[Hh][1-9]|"
#                         r"[Ll][1-9]"
#                         ")$"
#                         ) % (_, _, _, _, _, _, _, _),
#                         )
# 
# PAT_JUMPS = re.compile(_orjoin(PAT_VERTICAL_JUMPS,PAT_HORIZONTAL_JUMPS))
# 
# PAT_RELAYS = re.compile(r"^(?:(\d{1,2})[xX](\d{2,5}[hH]?|[rR][eE][lL][aA][yY]))$") # 4x100, 4x400, 4xReLAy, 12x200H
# 
# PAT_HURDLES = re.compile(r"^(?:(\d{2,4})(?:%s))$" % re.sub(r'\(\?P<[^>]*>','(',_)) # 80H, 110H, 400H
# 
# PAT_TRACK = re.compile(r"^(?:(?:(?P<meters>\d+)\s*(?P<msfx>%s|[yY]|[wW])?)|[sS][cC]|[2345][mM][tT]|[lL][hH]|[sS][hH])$" % _)
# 
# PAT_LEADING_DIGITS = re.compile(r"^\d+")
# 
# PAT_LEADING_FLOAT = re.compile(r"^\d+\.\d*")
# 
# PAT_PERF = re.compile(r"^(\d{1,2}:)?(\d{1,2}:)?(\d{1,2})(\.?\d+)?$")
# 
# PAT_LONG_SECONDS = re.compile(r"^\d{3,6}(\.?\d+)?$")
# 
# PAT_EVENT_CODE=re.compile(_orjoin(PAT_MULTI,PAT_RUN,
#                 PAT_FIELD,PAT_RELAYS,PAT_HURDLES,PAT_RACES_FOR_DISTANCE, 
#                 PAT_HIGHSCORING_EVENT, PAT_LOWSCORING_EVENT))
# 
# FIELD_EVENTS = JUMPS + THROWS
# 
# MULTI_EVENTS = (
#     # Greek prefixes for 2..12 events, and for 20.
#     "BI", "TRI", "QUAD", "PEN", "HEX", "HEP", "OCT", "ENN", "DEC",
#     "HEN", "DOD", "ICO",
# 
#     "PENI",  # Indoor Pentathlon, not sure if we should keep this
#     "PENWT",  # Weights Pentathlon - defines what events go in it.
# )
# 
# CUSTOM_EVENTS = CUSTOM_HIGHSCORING_EVENTS + CUSTOM_LOWSCORING_EVENTS
# 
# FIELD_SORT_ORDER = [
#         "HJ", "SHJ",
#         "PV", 
#         "LJ", "SLJ",
#         "TJ", "STJ",
#         "SP", "DT", "HT", "JT", 
#         "ST", "GDT", "BT", "WT", "SWT", "OT", "TART", "OHT", "CHT", "SDT", "SJT", "SBT",
#         "H1", "H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9",   #Custom Events
#         "L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8", "L9",   #Custom Events
#         ]
# 
# PAT_RACES_FOR_DISTANCE = re.compile(r"^(?:(?P<dhours>\d\d?)([hH](?:[rR]|[wW]))|[tT](?P<dmins>\d+))$")


# Path: athlib/utils.py
import sys, os, json
import jsonschema
import jsonschema.validators
import builtins
from collections import OrderedDict
from jsonschema.validators import RefResolver as OriginalResolver
from jsonschema.exceptions import SchemaError, ValidationError
from typing import Any, Union, Dict, Optional, Type, Tuple, Match, List, TypeVar
from .codes import PAT_THROWS, PAT_JUMPS, PAT_RELAYS, PAT_HURDLES, PAT_TRACK, \
    PAT_LEADING_DIGITS, PAT_LEADING_FLOAT, PAT_PERF, PAT_LONG_SECONDS, PAT_EVENT_CODE, \
    FIELD_EVENTS, MULTI_EVENTS, CUSTOM_EVENTS, FIELD_SORT_ORDER, PAT_RACES_FOR_DISTANCE

    if m:
        distance = int(m.group(1))
        return 1, distance, discipline

    # anything else sorts to end
    return 6, 0, discipline

def text_discipline_sort_key(discipline: str) -> str:
    "Return a text version of the event_sort_key"
    return "%d_%05d_%s" % discipline_sort_key(discipline)

T = TypeVar('T')

def sort_by_discipline(stuff: List[T], attr: str = "discipline") -> List[T]:
    "Sort dicts or objects into the normal athletics order"

    sorter = []
    for thing in stuff:
        if isinstance(thing, dict):
            disc = thing.get(attr, None)
        else:
            # assume object
            disc = getattr(thing, attr, None)
        priority = discipline_sort_key(disc)
        sorter.append((priority, thing))

    sorter.sort(key=lambda x: x[0])
    return [thing for (priority, thing) in sorter]

def check_event_code(c: str) -> Optional[Match[str]]:

    return PAT_EVENT_CODE.match(c)