# 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
    try:
        return str2num(t)
    except ValueError:
        raise ValueError('cannot parse seconds from %s' % repr(t))

def get_distance(discipline: str) -> Optional[int]:
    """
    Return approx distance in metres, for sanity checking
    :param discipline:
    :return:
    """

    # Ignore final words like ' road'

    discipline = discipline.split()[0]
    if discipline == "XC":
        return None
    elif discipline == 'MAR':
        return 42195
    elif discipline == "HM":
        return 21098
    elif discipline in ("MILE","CHUNDER-MILE"):
        return 1609

    m = PAT_RELAYS.match(discipline)
    if m:
        g2 = m.group(2).upper()
        if g2=='RELAY': return None #cowardly refusing to guess
        return int(m.group(1))*int(g2.rstrip('hH'))


# 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

    try:
        return str2num(t)
    except ValueError:
        raise ValueError('cannot parse seconds from %s' % repr(t))

def get_distance(discipline: str) -> Optional[int]:
    """
    Return approx distance in metres, for sanity checking
    :param discipline:
    :return:
    """

    # Ignore final words like ' road'

    discipline = discipline.split()[0]
    if discipline == "XC":
        return None
    elif discipline == 'MAR':
        return 42195
    elif discipline == "HM":
        return 21098
    elif discipline in ("MILE","CHUNDER-MILE"):
        return 1609

    m = PAT_RELAYS.match(discipline)
    if m:
        g2 = m.group(2).upper()
        if g2=='RELAY': return None #cowardly refusing to guess
        return int(m.group(1))*int(g2.rstrip('hH'))


    m = PAT_LEADING_FLOAT.match(discipline)