from dockstream.utils.enums.ligand_preparation_enum import LigandPreparationEnum


class OmegaExecutablesEnum(LigandPreparationEnum):
    """This "Enum" serves to store all OpenEye OMEGA ligand preparator strings and executables"""

    MODULE_LOAD_OMEGA = "module load omega"   # loads OMEGA 3.0.1.2, OMEGA 4.1.0.0 is the latest version with GPU support
    OMEGA_HELP_IDENTIFICATION_STRING = "A mode must be specified"   # string to identify whether OMEGA is available for a ligand embedding job

    OMEGA = "oeomega"
    # 5 supported modes
    # ----------------------------------------------------------------
    MODE = "mode"
    CLASSIC = "classic"   # The original customizable omega2 interface
    MACROCYCLE = "macrocycle"   # Conformer generation for macrocycles
    ROCS = "rocs"   # Optimal conformer generation for ROCS
    POSE = "pose"   # Optimal conformer generation for molecular alignment and pose prediction by docking
    DENSE = "dense"   # Optimal conformer generation for FREEFORM

    # Help Commands
    # ----------------------------------------------------------------
    HELP_SIMPLE = "--help simple"
    HELP_ALL = "--help all"

    # parallelization
    # ---------
    PARALLELIZATION = "parallelization"
    PARALLELIZATION_NUMBER_CORES = "number_cores"
    PARALLELIZATION_MAXCOMPOUNDSPERSUBJOB = "max_compounds_per_subjob"

    # Minimum Required Arguments For All Modes
    # ----------------------------------------------------------------
    IN = "-in"   # path to input ligands to embed
    OUT = "-out"   # desired output path for embedded ligands

    # Optional Execute Options For All Modes
    # ----------------------------------------------------------------
    PARAM = "-param"   # file containing all control parameters. Commands given explicitly via CLI supersede
                       # the parameter file. A new parameter file containing the full set of execution parameters
                       # is generated following OMEGA execution
    MPI_NP = "-mpi_np"   # number of MPI processes to launch
    MPI_HOSTFILE = "mpi_hostfile"   # path to hostfile to be used for launching MPI processes

    # *** OMEGA Classic Optional Parameters ***
    # File Options
    # ----------------------------------------------------------------
    CLASSIC_COMMENTENERGY = "-commentEnergy"   # writes conformer energies to the comment field, default=False
    CLASSIC_INCLUDEINPUT = "-includeInput"   # include input conformer in output file, input file must be in 3D format
                                             # such as SDF, MOL2, OEB, default=False
    CLASSIC_LOG = "-log"   # specifies the name of the log file
    CLASSIC_PENDINGFILE = "-pendingFile"   # specifies the name of the pending molecules file
    CLASSIC_PREFIX = "-prefix"   # specifies prefix for files generated by OMEGA classic, default="oeomega_classic"
    CLASSIC_PROGRESS = "-progress"   # display progress on screen: "none", "dots", "log", or "percent", default="none"
    CLASSIC_ROTOROFFSETCOMPRESS = "-rotorOffsetCompress"   # output compress OEBinary files, default=True
    CLASSIC_SDENERGY = "-sdEnergy"   # write conformer energies to the SD tag field
    CLASSIC_STATUS = "status"   # specifies the name for status report file
    CLASSIC_VERBOSE = "-verbose"   # denotes to include maximum information in log file, default=False
    CLASSIC_WARTS = "-warts"   # add conformer number wart to title of multiconformers

    # 3D Construction Parameters
    # ----------------------------------------------------------------
    CLASSIC_ADDFRAGLIB = "-addfraglib"   # file containing fragments used for 3D construction, in
                                         # addition to built-in fraglib.
    CLASSIC_BUILDFF = "-buildff"   # force field to use for initial structure refinement, default="mmff94smod_NoEstat"
    CLASSIC_CANONORDER = "-canonOrder"   # place atoms/bond in canonical order, default=True
    CLASSIC_DELETEFIXHYDROGENS = "-deleteFixHydrogens"   # deletes hydrogens from fixfile fragment, default=True
    CLASSIC_DIELECTRIC = "-dielectric"   # dielectric used for electrostatic calculations
    CLASSIC_FIXFILE = "-fixfile"   # file used to specify a user defined fragment. Molecules that do
                                   # not match will be sent to the fail file
    CLASSIC_FIXRMS = "-fixrms"   # RMS used to identify invalid superpositions onto fixfile template, default=0.15
    CLASSIC_FIXSMARTS = "-fixsmarts"   # SMARTS pattern used to fix portion of molecule. Molecules
                                       # that do not match will be sent to the fail file
    CLASSIC_FROMCT = "-fromCT"   # generate structures from connection-table only, default=True
    CLASSIC_MAXMATCH = "-maxmatch"   # maximum number of allowed matches of fixfile fragment
    CLASSIC_SETFRAGLIB = "-setfraglib"   # File containing fragments used for 3D construction. Replaces
                                         # built-in fraglib
    CLASSIC_STRICTFRAGS = "-strictfrags"   # most rigorous fragment generation: time limit for fragment generated
                                           # increased from 30 --> 300 seconds, default=False
    CLASSIC_STRICTATOMTYPING = "-strictatomtyping"   # Use strict atom typing for MMFF94 or allow "close enough" matching, default=False
    CLASSIC_UMATCH = "-umatch"   # only use unique matches for fixfile fragment replacement

    # Structure Enumeration
    # ----------------------------------------------------------------
    CLASSIC_ENUMNITROGEN = "-enumNitrogen"   # enumerate pyramidal invertible nitrogen geometries, default="unspecified"
    CLASSIC_ENUMRING = "-enumRing"   # enumerate ring conformers, default=True
    CLASSIC_SAMPLEHYDROGENS = "-sampleHydrogens"   # sample hydrogen positions for -OH, -SH, and amines, default=False

    # Torsion Driving Parameters
    # ----------------------------------------------------------------
    CLASSIC_ADDTORLIB = "-addtorlib"   # input name of torsion rules file, in addition to built-in torlib
    CLASSIC_ERANGE = "-erange"   # energy window values based on number of rotors
    CLASSIC_EWINDOW = "-ewindow"   # energy window used for conformer selection, default=10.0
    CLASSIC_MAXCONFRANGE = "-maxConfRange"   # maximum number of conformers based on number of rotors,
                                             # legal values are from 0 to 1000000
    CLASSIC_MAXCONFS = "-maxconfs"   # maximum number of conformations to be saved, default=200
    CLASSIC_MAXROT = "-maxrot"   # maximum number of rotatable bonds in a molecule, use -1 for no maximum, default = -1
    CLASSIC_MAXTIME = "-maxtime"   # maximum time (s) allowed for torsion search, default=120.0
    CLASSIC_RANGEINCREMENT = "-rangeIncrement"   # size of rotor groupings for range flags, default=5
    CLASSIC_RMS = "-rms"   # RMS threshold used to determine duplicate conformations, default=0.5
    CLASSIC_RMSRANGE = "-rmsrange"   # RMS threshold values based on number of rotors
    CLASSIC_SEARCHFF = "-searchff"   # force field to use during torsion search, default=mmff94smod_NoEstat
    CLASSIC_SETTORLIB = "-settorlib"   # input name of torsion rules, replaces built-in torlib.
    CLASSIC_TORLIBTYPE = "-torlibtype"   # type name of built-in torsion library. Specifies the type of built-in torlib, default="original"
    USE_GPU = "-useGPU"   # use GPU-OMEGA to accelerate torsion driving if a GPU is available, default=True

    # Stereo Parameters
    # ----------------------------------------------------------------
    CLASSIC_FLIPPER = "-flipper"   # Flips unspecified stereo centers, 'force' will flip all stereo centers, default=False
    CLASSIC_FLIPPER_MAXCENTERS = "-flipper_maxcenters"   # maximum number of chiral centers for exhaustive enumeration, default=12
    CLASSIC_FLIPPER_WARTS = "-flipper_warts"   # Add wart to title of each stereoisomer, default=True
    CLASSIC_STRICTSTEREO = "-strictstereo"   # Requires that all chiral atoms and bonds have specified stereo, default=True

    # General
    # ----------------------------------------------------------------
    CLASSIC_STRICT = "-strict"   # A convenience flag to set "-strictstereo", "-strictatomtyping", and
                                 # "-strictfrags" to True or False and override previous settings

    # *** OMEGA Macrocycle Optional Parameters ***
    # Options
    # ----------------------------------------------------------------
    MACROCYCLE_DIELECTRIC_CONSTANT = "-dielectric_constant"   # Value > 1 implies using solvation during refinement
                                                              # with specified dielectric constant
    MACROCYCLE_EWINDOW = "-ewindow"   # energy window for the output conformers, default=20.0
    MACROCYCLE_ITERATION_CYCLE_SIZE = "-iteration_cycle_size"   # Number of iterations to run before checking if a
                                                                # new minimum was found (run will finish if no new
                                                                # minimum is found), defaut=100
    MACROCYCLE_MAX_ITERATIONS = "-max_iterations"   # Maximum number of iterations (calculation may converge
                                                    # before reaching this number)
    MACROCYCLE_MAXCONFS = "-maxconfs"   # maximum number of conformations to be saved, default=400
    MACROCYCLE_REF_TOLERANCE = "-ref_tolerance"   # RMS gradient tolerance for force field refinement, default=0.001
    MACROCYCLE_RMS = "-rms"   # RMS clustering threshold (if 0.0 clustering is skipped), default=0.5
    MACROCYCLE_RMSD_DEDUPLICATE = "-rmsd_deduplicate"   # Deduplicate using a RMSD calcuation (slow) rather than
                                                        # energy and torsion comparison

    # *** OMEGA ROCS Optional Parameters ***
    # File Options
    # ----------------------------------------------------------------
    ROCS_LOG = "-log"  # specifies the name of the log file
    ROCS_PENDINGFILE = "-pendingFile"  # specifies the name of the pending molecules file
    ROCS_PREFIX = "-prefix"  # specifies prefix for files generated by OMEGA classic, default="oeomega_rocs"
    ROCS_PROGRESS = "-progress"  # display progress on screen: "none", "dots", "log", or "percent", default="none"
    ROCS_STATUS = "status"  # specifies the name for status report file
    ROCS_VERBOSE = "-verbose"  # denotes to include maximum information in log file, default=False
    ROCS_TORLIBTYPE = "-torlibtype"   # type name of built-in torsion library. Specifies the type of built-in torlib, default="original"

    # *** OMEGA Pose Optional Parameters ***
    # File Options
    # ----------------------------------------------------------------
    POSE_LOG = "-log"  # specifies the name of the log file
    POSE_PENDINGFILE = "-pendingFile"  # specifies the name of the pending molecules file
    POSE_PREFIX = "-prefix"  # specifies prefix for files generated by OMEGA classic, default="oeomega_pose"
    POSE_PROGRESS = "-progress"  # display progress on screen: "none", "dots", "log", or "percent", default="none"
    POSE_STATUS = "status"  # specifies the name for status report file
    POSE_VERBOSE = "-verbose"  # denotes to include maximum information in log file, default=False
    POSE_TORLIBTYPE = "-torlibtype"  # type name of built-in torsion library. Specifies the type of built-in torlib, default="original"

    # *** OMEGA Dense Optional Parameters ***
    # File Options
    # ----------------------------------------------------------------
    DENSE_LOG = "-log"  # specifies the name of the log file
    DENSE_PENDINGFILE = "-pendingFile"  # specifies the name of the pending molecules file
    DENSE_PREFIX = "-prefix"  # specifies prefix for files generated by OMEGA classic, default="oeomega_dense"
    DENSE_PROGRESS = "-progress"  # display progress on screen: "none", "dots", "log", or "percent", default="none"
    DENSE_STATUS = "status"  # specifies the name for status report file
    DENSE_VERBOSE = "-verbose"  # denotes to include maximum information in log file, default=False
    DENSE_TORLIBTYPE = "-torlibtype"  # type name of built-in torsion library. Specifies the type of built-in torlib, default="original"

    # try to find the internal value and return
    def __getattr__(self, name):
        if name in self:
            return name
        raise AttributeError

    # prohibit any attempt to set any values
    def __setattr__(self, key, value):
        raise ValueError("No changes allowed.")


class OmegaOutputEnum:

    LOG = ".log"



    # tags
    CLASSIC_ENERGY_OUTPUT_TAG = "mmff94smod_NoEstat"

    # other
    OUTPUT_SDF_NAME = "omega_out.sdf"                                # This hard-coded output name will be parsed.

    # try to find the internal value and return
    def __getattr__(self, name):
        if name in self:
            return name
        raise AttributeError

    # prohibit any attempt to set any values
    def __setattr__(self, key, value):
        raise ValueError("No changes allowed.")

















