from enum import Enum
from typing import Self


class Category(Enum):
    """
    All the categories in the arXiv subject taxonomy, mapped to their codes.

    See [Arxiv category taxonomy](https://arxiv.org/category_taxonomy)
    """

    def __new__(cls, value: str, description: str | None = None) -> Self:
        """Allows for custom descriptions for each enum value"""
        obj = object.__new__(cls)
        obj._value_ = value
        if description is not None:
            obj.__doc__ = description
        return obj

    # Computer Science
    CS_AI = "cs.AI", "Computer Science - Artificial Intelligence"
    CS_AR = "cs.AR", "Computer Science - Hardware Architecture"
    CS_CC = "cs.CC", "Computer Science - Computational Complexity"
    CS_CE = "cs.CE", "Computer Science - Computational Engineering; Finance; and Science"
    CS_CG = "cs.CG", "Computer Science - Computational Geometry"
    CS_CL = "cs.CL", "Computer Science - Computation and Language"
    CS_CR = "cs.CR", "Computer Science - Cryptography and Security"
    CS_CV = "cs.CV", "Computer Science - Computer Vision and Pattern Recognition"
    CS_CY = "cs.CY", "Computer Science - Computers and Society"
    CS_DB = "cs.DB", "Computer Science - Databases"
    CS_DC = "cs.DC", "Computer Science - Distributed; Parallel; and Cluster Computing"
    CS_DL = "cs.DL", "Computer Science - Digital Libraries"
    CS_DM = "cs.DM", "Computer Science - Discrete Mathematics"
    CS_DS = "cs.DS", "Computer Science - Data Structures and Algorithms"
    CS_ET = "cs.ET", "Computer Science - Emerging Technologies"
    CS_FL = "cs.FL", "Computer Science - Formal Languages and Automata Theory"
    CS_GL = "cs.GL", "Computer Science - General Literature"
    CS_GR = "cs.GR", "Computer Science - Graphics"
    CS_GT = "cs.GT", "Computer Science - Game Theory"
    CS_HC = "cs.HC", "Computer Science - Human-Computer Interaction"
    CS_IR = "cs.IR", "Computer Science - Information Retrieval"
    CS_IT = "cs.IT", "Computer Science - Information Theory"
    CS_LG = "cs.LG", "Computer Science - Machine Learning"
    CS_LO = "cs.LO", "Computer Science - Logic in Computer Science"
    CS_MA = "cs.MA", "Computer Science - Multiagent Systems"
    CS_MM = "cs.MM", "Computer Science - Multimedia"
    CS_MS = "cs.MS", "Computer Science - Mathematical Software"
    CS_NA = "cs.NA", "Computer Science - Numerical Analysis"
    CS_NE = "cs.NE", "Computer Science - Neural and Evolutionary Computing"
    CS_NI = "cs.NI", "Computer Science - Networking and Internet Architecture"
    CS_OH = "cs.OH", "Computer Science - Other"
    CS_OS = "cs.OS", "Computer Science - Operating Systems"
    CS_PF = "cs.PF", "Computer Science - Performance"
    CS_PL = "cs.PL", "Computer Science - Programming Languages"
    CS_RO = "cs.RO", "Computer Science - Robotics"
    CS_SC = "cs.SC", "Computer Science - Symbolic Computation"
    CS_SD = "cs.SD", "Computer Science - Sound"
    CS_SE = "cs.SE", "Computer Science - Software Engineering"
    CS_SI = "cs.SI", "Computer Science - Social and Information Networks"
    CS_SY = "cs.SY", "Computer Science - Systems and Control"
    # Economics
    ECON_EM = "econ.EM", "Economics - Econometrics"
    ECON_GN = "econ.GN", "Economics - General Economics"
    ECON_TH = "econ.TH", "Economics - Theoretical Economics"
    # Electrical Engineering and Systems Science
    EESS_AS = "eess.AS", "Electrical Engineering and Systems Science - Audio and Speech Processing"
    EESS_IV = "eess.IV", "Electrical Engineering and Systems Science - Image and Video Processing"
    EESS_SP = "eess.SP", "Electrical Engineering and Systems Science - Signal Processing"
    EESS_SY = "eess.SY", "Electrical Engineering and Systems Science - Systems and Control"
    # Mathematics
    MATH_AC = "math.AC", "Mathematics - Commutative Algebra"
    MATH_AG = "math.AG", "Mathematics - Algebraic Geometry"
    MATH_AP = "math.AP", "Mathematics - Analysis of PDEs"
    MATH_AT = "math.AT", "Mathematics - Algebraic Topology"
    MATH_CA = "math.CA", "Mathematics - Classical Analysis and ODEs"
    MATH_CO = "math.CO", "Mathematics - Combinatorics"
    MATH_CT = "math.CT", "Mathematics - Category Theory"
    MATH_CV = "math.CV", "Mathematics - Complex Variables"
    MATH_DG = "math.DG", "Mathematics - Differential Geometry"
    MATH_DS = "math.DS", "Mathematics - Dynamical Systems"
    MATH_FA = "math.FA", "Mathematics - Functional Analysis"
    MATH_GM = "math.GM", "Mathematics - General Mathematics"
    MATH_GN = "math.GN", "Mathematics - General Topology"
    MATH_GR = "math.GR", "Mathematics - Group Theory"
    MATH_GT = "math.GT", "Mathematics - Geometric Topology"
    MATH_HO = "math.HO", "Mathematics - History and Overview"
    MATH_IT = "math.IT", "Mathematics - Information Theory"
    MATH_KT = "math.KT", "Mathematics - K-Theory and Homology"
    MATH_LO = "math.LO", "Mathematics - Logic"
    MATH_MG = "math.MG", "Mathematics - Metric Geometry"
    MATH_MP = "math.MP", "Mathematics - Mathematical Physics"
    MATH_NA = "math.NA", "Mathematics - Numerical Analysis"
    MATH_NT = "math.NT", "Mathematics - Number Theory"
    MATH_OA = "math.OA", "Mathematics - Operator Algebras"
    MATH_OC = "math.OC", "Mathematics - Optimization and Control"
    MATH_PR = "math.PR", "Mathematics - Probability"
    MATH_QA = "math.QA", "Mathematics - Quantum Algebra"
    MATH_RA = "math.RA", "Mathematics - Rings and Algebras"
    MATH_RT = "math.RT", "Mathematics - Representation Theory"
    MATH_SG = "math.SG", "Mathematics - Symplectic Geometry"
    MATH_SP = "math.SP", "Mathematics - Spectral Theory"
    MATH_ST = "math.ST", "Mathematics - Statistics Theory"
    # Physics
    # - Astrophysics
    ASTRO_PH_CO = "astro-ph.CO", "Astrophysics - Cosmology and Nongalactic Astrophysics"
    ASTRO_PH_EP = "astro-ph.EP", "Astrophysics - Earth and Planetary Astrophysics"
    ASTRO_PH_GA = "astro-ph.GA", "Astrophysics - Astrophysics of Galaxies"
    ASTRO_PH_HE = "astro-ph.HE", "Astrophysics - High Energy Astrophysical Phenomena"
    ASTRO_PH_IM = "astro-ph.IM", "Astrophysics - Instrumentation and Methods for Astrophysics"
    ASTRO_PH_SR = "astro-ph.SR", "Astrophysics - Solar and Stellar Astrophysics"
    # - Condensed Matter
    COND_MAT_DIS_NN = "cond-mat.dis-nn", "Condensed Matter - Disordered Systems and Neural Networks"
    COND_MAT_MES_HALL = "cond-mat.mes-hall", "Condensed Matter - Mesoscale and Nanoscale Physics"
    COND_MAT_MTRL_SCI = "cond-mat.mtrl-sci", "Condensed Matter - Materials Science"
    COND_MAT_OTHER = "cond-mat.other", "Condensed Matter - Other Condensed Matter"
    COND_MAT_SOFT = "cond-mat.soft", "Condensed Matter - Soft Condensed Matter"
    COND_MAT_STAT_MECH = "cond-mat.stat-mech", "Condensed Matter - Statistical Mechanics"
    COND_MAT_STR_EL = "cond-mat.str-el", "Condensed Matter - Strongly Correlated Electrons"
    COND_MAT_SUPR_CON = "cond-mat.supr-con", "Condensed Matter - Superconductivity"
    # - General Relativity
    GR_QC = "gr-qc", "General Relativity and Quantum Cosmology"
    # - High Energy Physics
    HEP_EX = "hep-ex", "High Energy Physics - Experiment"
    HEP_LAT = "hep-lat", "High Energy Physics - Lattice"
    HEP_PH = "hep-ph", "High Energy Physics - Phenomenology"
    HEP_TH = "hep-th", "High Energy Physics - Theory"
    # - Mathematical Physics
    MATH_PH = "math-ph", "Mathematical Physics"
    # - Nonlinear Sciences
    NLIN_AO = "nlin.AO", "Nonlinear Sciences - Adaptation and Self-Organizing Systems"
    NLIN_CD = "nlin.CD", "Nonlinear Sciences - Chaotic Dynamics"
    NLIN_CG = "nlin.CG", "Nonlinear Sciences - Cellular Automata and Lattice Gases"
    NLIN_PS = "nlin.PS", "Nonlinear Sciences - Pattern Formation and Solitons"
    NLIN_SI = "nlin.SI", "Nonlinear Sciences - Exactly Solvable and Integrable Systems"
    # - Nuclear Physics
    NUCL_EX = "nucl-ex", "Nuclear Experiment"
    NUCL_TH = "nucl-th", "Nuclear Theory"
    # - General Physics
    PHYSICS_ACC_PH = "physics.acc-ph", "Physics - Accelerator Physics"
    PHYSICS_AO_PH = "physics.ao-ph", "Physics - Atmospheric and Oceanic Physics"
    PHYSICS_APP_PH = "physics.app-ph", "Physics - Applied Physics"
    PHYSICS_ATM_CLUS = "physics.atm-clus", "Physics - Atomic and Molecular Clusters"
    PHYSICS_ATOM_PH = "physics.atom-ph", "Physics - Atomic Physics"
    PHYSICS_BIO_PH = "physics.bio-ph", "Physics - Biological Physics"
    PHYSICS_CHEM_PH = "physics.chem-ph", "Physics - Chemical Physics"
    PHYSICS_CLASS_PH = "physics.class-ph", "Physics - Classical Physics"
    PHYSICS_COMP_PH = "physics.comp-ph", "Physics - Computational Physics"
    PHYSICS_DATA_AN = "physics.data-an", "Physics - Data Analysis; Statistics and Probability"
    PHYSICS_ED_PH = "physics.ed-ph", "Physics - Physics Education"
    PHYSICS_FLU_DYN = "physics.flu-dyn", "Physics - Fluid Dynamics"
    PHYSICS_GEN_PH = "physics.gen-ph", "Physics - General Physics"
    PHYSICS_GEO_PH = "physics.geo-ph", "Physics - Geophysics"
    PHYSICS_HIST_PH = "physics.hist-ph", "Physics - History and Philosophy of Physics"
    PHYSICS_INS_DET = "physics.ins-det", "Physics - Instrumentation and Detectors"
    PHYSICS_MED_PH = "physics.med-ph", "Physics - Medical Physics"
    PHYSICS_OPTICS = "physics.optics", "Physics - Optics"
    PHYSICS_PLASM_PH = "physics.plasm-ph", "Physics - Plasma Physics"
    PHYSICS_POP_PH = "physics.pop-ph", "Physics - Popular Physics"
    PHYSICS_SOC_PH = "physics.soc-ph", "Physics - Physics and Society"
    PHYSICS_SPACE_PH = "physics.space-ph", "Physics - Space Physics"
    # - Quantum Physics
    QUANT_PH = "quant-ph", "Quantum Physics"
    # Quantitative Biology
    Q_BIO_BM = "q-bio.BM", "Quantitative Biology - Biomolecules"
    Q_BIO_CB = "q-bio.CB", "Quantitative Biology - Cell Behavior"
    Q_BIO_GN = "q-bio.GN", "Quantitative Biology - Genomics"
    Q_BIO_MN = "q-bio.MN", "Quantitative Biology - Molecular Networks"
    Q_BIO_NC = "q-bio.NC", "Quantitative Biology - Neurons and Cognition"
    Q_BIO_OT = "q-bio.OT", "Quantitative Biology - Other"
    Q_BIO_PE = "q-bio.PE", "Quantitative Biology - Populations and Evolution"
    Q_BIO_QM = "q-bio.QM", "Quantitative Biology - Quantitative Methods"
    Q_BIO_SC = "q-bio.SC", "Quantitative Biology - Subcellular Processes"
    Q_BIO_TO = "q-bio.TO", "Quantitative Biology - Tissues and Organs"
    # Quantitative Finance
    Q_FIN_CP = "q-fin.CP", "Quantitative Finance - Computational Finance"
    Q_FIN_EC = "q-fin.EC", "Quantitative Finance - Economics"
    Q_FIN_GN = "q-fin.GN", "Quantitative Finance - General Finance"
    Q_FIN_MF = "q-fin.MF", "Quantitative Finance - Mathematical Finance"
    Q_FIN_PM = "q-fin.PM", "Quantitative Finance - Portfolio Management"
    Q_FIN_PR = "q-fin.PR", "Quantitative Finance - Pricing of Securities"
    Q_FIN_RM = "q-fin.RM", "Quantitative Finance - Risk Management"
    Q_FIN_ST = "q-fin.ST", "Quantitative Finance - Statistical Finance"
    Q_FIN_TR = "q-fin.TR", "Quantitative Finance - Trading and Market Microstructure"
    # Statistics
    STAT_AP = "stat.AP", "Statistics - Applications"
    STAT_CO = "stat.CO", "Statistics - Computation"
    STAT_ME = "stat.ME", "Statistics - Methodology"
    STAT_ML = "stat.ML", "Statistics - Machine Learning"
    STAT_OT = "stat.OT", "Statistics - Other Statistics"
    STAT_TH = "stat.TH", "Statistics - Statistics Theory"
