# This code is part of OpenFE and is licensed under the MIT license.
# For details, see https://github.com/OpenFreeEnergy/openfe

from plugcli.params import MultiStrategyGetter, Option, NOT_PARSED


def _load_molecule_from_smiles(user_input, context):
    from openfe import SmallMoleculeComponent
    from rdkit import Chem
    # MolFromSmiles returns None if the string is not a molecule
    # TODO: find some way to redirect the error messages? Messages stayed
    # after either redirect_stdout or redirect_stderr.
    mol = Chem.MolFromSmiles(user_input)
    if mol is None:
        return NOT_PARSED

    # TODO: next is (temporary?) hack: see
    # https://github.com/OpenFreeEnergy/Lomap/issues/4
    Chem.rdDepictor.Compute2DCoords(mol)
    return SmallMoleculeComponent(rdkit=mol)


def _load_molecule_from_sdf(user_input, context):
    if '.sdf' not in str(user_input):  # this silences some stderr spam
        return NOT_PARSED

    from openfe import SmallMoleculeComponent
    try:
        return SmallMoleculeComponent.from_sdf_file(user_input)
    except ValueError:  # any exception should try other strategies
        return NOT_PARSED


def _load_molecule_from_mol2(user_input, context):
    if '.mol2' not in str(user_input):
        return NOT_PARSED

    from rdkit import Chem
    from openfe import SmallMoleculeComponent

    m = Chem.MolFromMol2File(user_input)
    if m is None:
        return NOT_PARSED
    else:
        return SmallMoleculeComponent(m)


get_molecule = MultiStrategyGetter(
    strategies=[
        _load_molecule_from_sdf,
        _load_molecule_from_mol2,
        # NOTE: I think loading from smiles must be last choice, because
        # failure will give meaningless user-facing errors
        _load_molecule_from_smiles,
    ],
    error_message="Unable to generate a molecule from '{user_input}'."
)

MOL = Option(
    "-m", "--mol",
    help=("SmallMoleculeComponent. Can be provided as an SDF file or as a SMILES "
          " string."),
    getter=get_molecule
)
