# Copyright (c) 2013-2020, SIB - Swiss Institute of Bioinformatics and
#                          Biozentrum - University of Basel
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#   http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import unittest
import os
from ost import conop
from ost import io

class SetCompoundsChemlibTests(unittest.TestCase):
    def testNoCompoundsLibOverwrite(self):
        # Checking that we DO NOT automatically load a compounds library if we
        # already got one. This is for the case that somebody loads her own lib
        # for whatever purpose so promod3 should not overwrite it on import.
        # For the test, we load a library here with a modified aa and check that
        # its still modified after importing promod3.

        # load compounds lib like in __init__.py.in
        compound_lib_path = os.path.join('data', 'broken_on_purpose.chemlib')
        clib = conop.CompoundLib.Load(compound_lib_path)
        self.assertIsNotNone(clib)
        conop.SetDefaultLib(clib)
        io.profiles['DEFAULT'].processor = conop.RuleBasedProcessor(clib)
        clib = conop.GetDefaultLib()

        # check amino acid
        fake_gly = ('GLY', 'IOU a formula')
        cmpd = clib.FindCompound(fake_gly[0])
        self.assertIsNotNone(cmpd)
        self.assertEqual(cmpd.formula, fake_gly[1])

        # import promod3, fetch default lib again, rerun test
        import promod3# pylint: disable=unused-variable
        clib = conop.GetDefaultLib()
        cmpd = clib.FindCompound(fake_gly[0])
        self.assertIsNotNone(cmpd)
        self.assertEqual(cmpd.formula, fake_gly[1])

    def testCompoundsLibLoadedOnImport(self):
        # Check that importing promod3 loads the compounds library. First we
        # test that we do not have a lib before importing, afterwards we import
        # and check for Glycine. This test reads the systems/ installed lib
        # which means an external data dependency. Lets assume this is OK: if
        # we do not have a chemical components dictionary, we do not know amino
        # acids, so ProMod3 would not work... We also check for essential
        # compounds in the library. Of course, those are amino acids and... if
        # there is something you really cannot live without, add it here. One
        # drawback of going by the systems lib, which should be updated every
        # week, is that things may change and then our compounds list here will
        # have to be updated, too.

        # before importing, we do not want to see a lib
        clib = conop.GetDefaultLib()
        self.assertIsNone(clib)

        # now there should be one
        import promod3# pylint: disable=unused-variable
        clib = conop.GetDefaultLib()
        self.assertIsNotNone(clib)

        # and it should feature Glycine
        gly = ('GLY', 'C2 H5 N O2')
        cmpd = clib.FindCompound(gly[0])
        self.assertIsNotNone(cmpd)
        self.assertEqual(cmpd.formula, gly[1])

        # checking selected compounds
        cmpnds = [('ALA', 'C3 H7 N O2'), ('ASX', 'C4 H6 N O2 X2'),
                  ('CYS', 'C3 H7 N O2 S'), ('ASP', 'C4 H7 N O4'),
                  ('GLU', 'C5 H9 N O4'), ('PHE', 'C9 H11 N O2'),
                  ('GLY', 'C2 H5 N O2'), ('HIS', 'C6 H10 N3 O2'),
                  ('ILE', 'C6 H13 N O2'), ('LYS', 'C6 H15 N2 O2'),
                  ('LEU', 'C6 H13 N O2'), ('MET', 'C5 H11 N O2 S'),
                  ('ASN', 'C4 H8 N2 O3'), ('PRO', 'C5 H9 N O2'),
                  ('GLN', 'C5 H10 N2 O3'), ('ARG', 'C6 H15 N4 O2'),
                  ('SER', 'C3 H7 N O3'), ('THR', 'C4 H9 N O3'),
                  ('VAL', 'C5 H11 N O2'), ('TRP', 'C11 H12 N2 O2'),
                  ('TYR', 'C9 H11 N O3'), ('GLX', 'C5 H8 N O2 X2'),
                  ('ADE', 'C5 H5 N5'), ('GUN', 'C5 H5 N5 O'),
                  ('CYT', 'C4 H5 N3 O'), ('THM', 'C10 H14 N2 O5'),
                  ('URA', 'C4 H4 N2 O2')]
        for cmpnd in cmpnds:
            entry = clib.FindCompound(cmpnd[0])
            self.assertIsNotNone(entry, msg="Compound '%s' not " % cmpnd[0]+
                                 "found in default compounds library.")
            self.assertEqual(entry.formula, cmpnd[1])

if __name__ == "__main__":
    from ost import testutils
    testutils.RunTests()

#  LocalWords:  unittest sys os ost conop io clib SetCompoundsChemlibTests aa
#  LocalWords:  TestCase testNoCompoundsLibOverwrite promod chemlib gly GLY
#  LocalWords:  assertIsNotNone SetDefaultLib RuleBasedProcessor cmpd ProMod
#  LocalWords:  GetDefaultLib FindCompound testCompoundsLibLoadedOnImport ASX
#  LocalWords:  assertIsNone cmpnds CYS GLU PHE ILE LYS LEU ASN GLN ARG SER
#  LocalWords:  THR TRP TYR GLX CYT THM URA cmpnd msg testutils RunTests
