from enum import Enum


class LDEnum(str, Enum):

    @classmethod
    def from_str(cls, value):
        return cls(value.lower())


class QueryConditionValueType(LDEnum):
    """
    Query condition value type. Used to denote a type of search, query, filter, etc.
    """
    VALUE = "value"
    NUMERIC_RANGE = "numeric_range"
    DATE_RANGE = "date_range"
    EXACT = "exact"
    SUBSTRUCTURE = "substructure"
    SIMILARITY = "similarity"
    RELATIVE_DATE = "relative_date"


class ColorStyleType(LDEnum):
    NUMBER = "number"
    DATE = "date"
    CATEGORICAL = "categorical"


class StructureTransformation(LDEnum):
    """
    Structure transformation.  Used, e.g., to describe a structure attachment.
    """
    FILE_UPLOAD = "file_upload"
    TRUNCATED = "truncated"


class PoseFormat(LDEnum):
    """
    Pose format. The file extension of the pose file.
    """
    PSE = "pse"
    MAE = "mae"
    MAEGZ = "maegz"


class NightlyTaskType(LDEnum):
    """
    Nightly task type. These tasks are performed nightly by the server, but can also be executed on demand.
    """
    LIVE_REPORT_NOTIFIER = "live_report_notifier"
    ORPHAN_FORMULAS_DELETE = "orphan_formulas_delete"
    EXPIRED_ASYNC_TASK_DELETE = "expired_async_task_delete"
    REFRESH_LIVE_REPORT_CACHE = "refresh_live_report_cache"
    CALCULATE_LIVE_REPORT = "calculate_live_report"
    AUTOSUGGEST_CACHE_UPDATE = "autosuggest_cache_update"
    CACHE_INVALIDATE = "cache_invalidate"
    LOG_SCALE_UPDATE = "log_scale_update"
    FILE_STORE_IMAGE_INVALIDATE = "file_store_image_invalidate"
    VACUUM_TASK = "vacuum_task"
    REMOVE_DUPLICATE_MANY_TO_MANY_ROWS = "remove_duplicate_many_to_many_rows"
    CLEAR_DEAD_SUBMITTED_TASKS = "clear_dead_submitted_tasks"
    DUMMY_COLUMNS_WITHOUT_OBSERVATIONS = "dummy_columns_without_observations"


class InvalidateCacheRequestType(LDEnum):
    """
    Invalidate cache request type. How the cache is being invalidated - e.g. by LiveReport, by entity, etc.
    """
    LIVE_REPORT_ROW_REMOVAL = "live_report_row_removal"
    LIVE_REPORT_CHANGE = "live_report_change"
    OBSERVATION_CHANGE = "observation_change"
    ENTITY_CHANGE = "entity_change"


class AssayColumnType(LDEnum):
    """
    Represents whether or not an assay column is 3D.
    """
    ASSAY = "assay"
    THREE_D = "three_d"


class ColumnFolderNodeType(LDEnum):
    """
    Represents types of :class:`~ldclient.responses.ColumnFolderNode`
    """
    ROOT = "root"
    TOP_LEVEL = "top_level"
    INNER = "inner"
    LEAF = "leaf"
    ROLLUP = "rollup"
    ADD_ALL = "add_all"
    CREATE_BUTTON = "create_button"
    ADD_ALL_ASSAYS = "add_all_assays"


class CompoundFormat(LDEnum):
    """
    Represents possible formats of a compound.
    """
    JSON = "json"
    JPEG = "jpeg"
    PNG = "png"
    SVG = "svg"
    MOL = "mol"
    SMILES = "smiles"
    MRV = "mrv"


class AddableColumnType(LDEnum):
    """
    Represents types of addable columns.
    """
    ASSAY = "assay"
    SUBSTRUCTURE = "substructure"
    MODEL = "model"
    DATABASE = "database"
    MPO = "mpo"
    MPO_DESIRABILITY_SCORE = "mpo_desirability_score"
    ID = "id"
    COMPOUND_STRUCTURE = "compound"
    COMPOUND_ATTRIBUTE = "database"
    OLED_RECIPE = "oled_recipe"
    RATIONALE = "rationale"
    SCAFFOLD = "scaffold"
    SCAFFOLD_ATTRIBUTE = "scaffold"
    ENUMERATION = "enumeration"
    R_GROUP = "r_group"
    FREEFORM = "freeform"
    FORMULA = "formula"
    ASSAY_DO_NOT_AGGREGATE = "assay_do_not_aggregate"
    ASSAY_LIMITED = "assay_limited"
    ASSAY_LIMITED_DO_NOT_AGGREGATE = "assay_limited_do_not_aggregate"
    LIGAND_DESIGNER = "ligand_designer"
    SIMILARITY_SCORE = "similarity_score"


class ValueType(LDEnum):
    """
    Represents types of cell values in a LiveReport.
    """
    INTEGER = "integer"
    FLOAT = "float"
    STRING = "string"
    PDB_DATA = "pdb_data"
    RATIONALE = "rationale"
    MOLECULE = "molecule"
    DATE = "date"
    DATETIME = "datetime"
    ATTACHMENT = "attachment"
    THREE_D = "3d"
    VARIABLE = "variable"
    IMAGE = "image"
    BOOLEAN = "boolean"
    ANIMATION = "animation"


class DisplayColumnType(LDEnum):
    """
    Represents types of columns, as displayed to the LiveDesign user.
    """
    COMPUTED_PROPERTY = "computed properties"
    COMPUTATIONAL_MODEL = "computational models"
    EXPERIMENTAL_ASSAY = "experimental assays"
    PROJECT_FAVORITES = "project favorites"
    MPO = "multi-parameter profiles"
    FORMULAS = "formulas"
    FREEFORM = "freeform columns"
    DATABASE = "other columns"


class AttachmentType(LDEnum):
    """
    Represents types of attachment files.
    """
    IMAGE = "image"
    ATTACHMENT = "attachment"
    THREE_D = "three_d"
    GLIDE_GRID_FILE = "glide_grid_file"
    GLIDE_TARGET = "glide_target"
    GLIDE_REFERENCE = "glide_reference"
    GLIDE_INPUT = "glide_input"


class ReportLevel(LDEnum):
    """
    Represents LiveReport level.
    """
    PARENT = 'parent'
    PARENT_BATCH = 'parent_batch'
    PARENT_SALT = 'parent_salt'
    PARENT_BATCH_SALT = 'parent_batch_salt'
    PARENT_BATCH_EXPERIMENT = 'parent_batch_experiment'
    POSE = 'pose'


class LiveReportViewMode(LDEnum):
    """
    Represents the view mode of a LiveReport.
    """
    SPREADSHEET = "spreadsheet"
    TILE = "tile"


class LiveReportResultVersionState(LDEnum):
    """
    Represents the state of a LiveReport result version.
    """
    ERROR = "error"
    EXISTS = "exists"


class LigandDesignerOverlayType(LDEnum):
    """
    Represents type of ligand designer overlay.
    """
    WATERMAP = "watermap"
    OTHER = "other"


class DockingPrecision(LDEnum):
    """
    Represents precision to use for Glide Docking.
    HTVS stands for High Throughput Virtual Screening.
    SP stands for Standard Precision.
    """
    HTVS = "HTVS"
    SP = "SP"


class EntityType(LDEnum):
    COMPOUND = "compound"
    SAMPLE = "sample"
    FRAGMENT = "fragment"
    DEVICE = "device"
    FORMULATION = "formulation"
    GENERIC_ENTITY = "generic_entity"


class CellAggregationType(LDEnum):
    MEDIAN = "median"
    ARITHMETIC_MEAN = "arithmetic_mean"
    MIN = "min"
    MAX = "max"
    GEOMETRIC_MEAN = "geometric_mean"
    SYSTEM_DEFAULT = "system_default"
    STD_DEV = "std_dev"
    COUNT = "count"
    LATEST = "latest"
    UNAGGREGATED = "unaggregated"
    LOGIT_MEAN = "logit_mean"
    HARMONIC_MEAN = "harmonic_mean"


class PropertyCategory(LDEnum):
    SETTINGS = "settings"
    CONFIGURATIONS = "configurations"
    DEVELOPMENT_FLAGS = "development_flags"
    INTERNAL_PROPERTIES = "internal_properties"


class PropertySubCategory(LDEnum):
    FEATURE_SETTINGS = "feature_settings"
    DATA_SETTINGS = "data_settings"
    SCIENTIFIC_SETTINGS = "scientific_settings"
    RESOURCE_MANAGEMENT = "resource_management"
    DATA_SEARCH_LIMITS = "data_search_limits"
    CUSTOM_WORKAROUNDS = "custom_workarounds"
    CORE_CONFIGURATION = "core_configuration"
    NEW_FUNCTIONALITY_FLAGS = "new_functionality_flags"
    BUG_PATCH_FLAGS = "bug_patch_flags"
    MIGRATION_FLAGS = "migration_flags"
    DEPLOYMENT_CONFIGURATIONS = "deployment_configurations"
    DEBUGGING_CONFIGURATIONS = "debugging_configurations"
    OTHER_INTERNAL_STATE = "other_internal_state"


class PropertyAclLevel(LDEnum):
    ADMIN = "admin"
    USER = "user"
    NONE = "none"


class PropertyManagedBy(LDEnum):
    SA = "sa"
    CHEF = "chef"
    CODE = "code"


class ModelReturnType(LDEnum):
    REAL = "real"
    STRING = "string"
    INTEGER = "integer"
    BOOLEAN = "boolean"
    PROTEIN = "3d structure target"
    LIGAND = "3d structure ligand"
    IMAGE = "image"
    ATTACHMENT = "attachment"
    ANIMATION = "3d structure animation"
    OTHER_3D = "Other 3d structure"


class ModelCommandType(LDEnum):
    REALTIME = "realtime"
    CLICK_TO_RUN = "click_to_run"
    CLUSTERING = "clustering"
    NORMAL = "normal"


class TaskEngineQueue(LDEnum):
    SYNC = "sync"
    FAST = "fast"
    ASYNC = "async"
    REALTIME = "realtime"


class RecursiveTag(LDEnum):
    """
    This describes how the data in a child structure should recursively be merged with the data in its parent. Options are:

    - DEFAULT: Takes a value, sets it as the default value, but can be overridden
    - ABSTRACT: Does NOT take a value, states that this field is explicitly blank
    - DELETE: Does NOT take a value, states that the value that was in this field should be removed
    - PASS: Does NOT take a value, states that this field should be copied verbatim from the parent
    - READ_ONLY: Takes a value, sets it as the default value, but can NOT be overridden.
    """
    DEFAULT = "default"
    ABSTRACT = "abstract"
    DELETE = "delete"
    PASS = "pass"
    READ_ONLY = "read_only"


class ModelTemplateVarType(LDEnum):
    INTEGER = "NUMERIC-INPUT"
    STRING = "TEXT-INPUT"
    LIVEDESIGN_URL = "LIVEDESIGN-URL"
    SDF_FILE = "SDF-FILE"
    ORIGINAL_SDF = "ORIG-SDF-FILE"
    HARDCODED_PCD_DRIVER = "HARDCODED_PCD_DRIVER"
    HARDCODED_MCS_DRIVER = "HARDCODED_MCS_DRIVER"
    FILE = "FILE-INPUT"
    COLUMN = "COLUMN-INPUT"
    MULTI_COLUMN = "MULTI-COLUMN-INPUT"
    ENTITY_FILE = "ENTITY-FILE"


class ModelSearchType(LDEnum):
    """
    This describes the model search types for model types query in models search. Options are:

        -"MODEL" For all models, excluding protocols
        -"NON_PARAMETERIZED_MODEL" For all models, excluding protocols and parameterized models
        -"PARAMETERIZED" For parameterized models
        -"PARAMETERIZABLE" For all models that are further parameterizable
        -"PROTOCOL" For all protocols
    """
    MODEL = "model"
    NON_PARAMETERIZED_MODEL = "non_parameterized_model"
    PARAMETERIZED = "parameterized"
    PARAMETERIZABLE = "parameterizable"
    PROTOCOL = "protocol"


class ModelPicklistType(LDEnum):
    """
    This describes the types of data that can be added to a model picklist group:

    - NUMERIC: Allows any numeric values to be added to the picklist
    - STRING: Allows any text based values to be added to the picklist
    - UNTYPED (default): UNTYPED is the default type for a picklist and is used when LIST-INPUT is defined in a
        protocols command, but the request has not defined a different type for the picklist.
        Items CANNOT be added to an UNTYPED picklist so its type must be changed to any different type to allow items to
        be added
    """
    NUMERIC = "NUMERIC"
    STRING = "STRING"
    UNTYPED = "UNTYPED"


class MPOConstituentType(LDEnum):
    """
    This describes the profile or rules associated with an MPO constituent. Options are:

        -"MONO" For a simple low-to-high numeric profile
        -"BELL" For a bell-curve type numeric profile, with 4 thresholds and option to prefer middle or extremes
        -"CATEGORY" For a simple categorical profile, where individual values are marked as "good", "bad", or "ok
    """
    MONO = "mono"
    BELL = "bell"
    CATEGORY = "category"


class EntityAliasAvailability(LDEnum):
    """
    Describes the availability status of  EntityAlias

        - "UNCLAIMED" No entity has this alias
        - "EMPTY" An generic entity has this alias, but has a null manageable file (therefore, this "alias" can be updated)
        - "UNAVAILABLE" This alias points to an non-generic entity, or an generic entity with a non-null manageable file
        - "INVALID" This alias is invalid & doesn't point to any entity
    """
    UNCLAIMED = "unclaimed"
    EMPTY = "empty"
    UNAVAILABLE = "unavailable"
    INVALID = "invalid"


class GenericEntityImportDataType(LDEnum):
    """
    Describes the accepted import types
        - "SINGLE_ENTITY" Accept a single Entity
        - "CSV_ROW_PER_ENTITY" Accept CSV rows for each entity
        - "ZIP_FILE_PER_ENTITY" Accept zip files for each entity
    """
    SINGLE_ENTITY = "single_entity"
    CSV_ROW_PER_ENTITY = "csv_row_per_entity"
    ZIP_FILE_PER_ENTITY = "zip_file_per_entity"


class ManageableFileUploadType(LDEnum):
    ENTITY = "entity"
    CSV_PARENT = "csv_parent"
    ZIP_PARENT = "zip_parent"


class ScaffoldFormat(LDEnum):
    """
    Represents possible formats of a compound.
    """
    PNG = "png"
    SVG = "svg"
    MOL3 = "mol:V3"


class AddableColumnValueTypeState(LDEnum):
    """
    Represents the state of addable column value type.
    """
    UNKNOWN = "UNKNOWN"
    KNOWN = "KNOWN"
    NOT_SUPPORTED = "NOT_SUPPORTED"


class CompoundIdentifierType(LDEnum):
    """
    Type of data in the compound identifier column for imported files
    """
    CSV_CORP_ID = "CSV_CORP_ID"
    CSV_SMILES = "CSV_SMILES"