# Path: metatlas/datastructures/metatlas_objects.py
# FETCH_STUBS = True
# ADDUCTS = ('','[M]+','[M+H]+','[M+H]2+','[M+2H]2+','[M+H-H2O]2+','[M+K]2+','[M+NH4]+','[M+Na]+','[M+H-H2O]+','[M-H]-','[M-2H]-','[M-H+Cl]-','[M-2H]2-','[M+Cl]-','[2M+H]+','[2M-H]-','[M-H+Na]+','[M+K]+','[M+2Na]2+','[M-e]+','[M+acetate]-','[M+formate]-','[M-H+Cl]2-','[M-H+2Na]+')
# POLARITY = ('positive', 'negative', 'alternating')
# FRAGMENTATION_TECHNIQUE = ('hcd','cid','etd','ecd','irmpd')
# ID_GRADES: Dict[str, IdentificationGrade] = dict()
#     FETCH_STUBS = False
#         FETCH_STUBS = True
#     FETCH_STUBS = True
# def retrieve(object_type, **kwargs):
# def remove(object_type, **kwargs):
# def remove_objects(objects, all_versions=True, **kwargs):
# def store(objects, **kwargs):
#     def __init__(self, **kwargs):
#     def _update(self, override_user=False):
#     def clone(self, recursive=False):
#     def show_diff(self, unique_id=None):
#     def _on_update(self, change):
#     def __str__(self):
#     def __repr__(self):
#     def __getattribute__(self, name):
#     def validate(self, obj, value):
# def find_invalid_runs(**kwargs):
# def to_dataframe(objects):
# class MetatlasObject(HasTraits):
# class Method(MetatlasObject):
# class Sample(MetatlasObject):
# class LcmsRun(MetatlasObject):
# class FunctionalSet(MetatlasObject):
# class Compound(MetatlasObject):
# class Reference(MetatlasObject):
# class IdentificationGrade(MetatlasObject):
# class _IdGradeTrait(MetInstance):
# class Group(MetatlasObject):
# class MzIntensityPair(MetatlasObject):
# class FragmentationReference(Reference):
# class RtReference(Reference):
# class MzReference(Reference):
# class IntensityReference(Reference):
# class CompoundIdentification(MetatlasObject):
# class Atlas(MetatlasObject):
# class MZMineTask(MetatlasObject):
# 
# Path: metatlas/datastructures/object_helpers.py
# ON_NERSC = 'METATLAS_LOCAL' not in os.environ
# def callback_method(func):
#     def notify(self, *args, **kwargs):
#     def __getitem__(self, item):
#     def __init__(self, *args):
#     def register_callback(self, cb):
#     def unregister_callback(self, cbid):
# def set_docstring(cls):
# def _get_subclasses(cls):
#     def __init__(self):
#     def get_instance(cls):
#     def get_connection(self):
#     def close_connection(self):
#     def convert_to_double(self, table, entry):
#     def save_objects(self, objects, _override=False):
#     def create_link_tables(self, klass):
#     def _get_save_data(self, obj, override=False):
#     def fix_table(self, table_name):
#     def retrieve(self, object_type, **kwargs):
#     def remove(self, object_type, **kwargs):
#     def remove_objects(self, objects, all_versions=True, **kwargs):
# def format_timestamp(tstamp):
#     def validate(self, obj, value):
#     def retrieve(self):
#     def __repr__(self):
#     def __str__(self):
#     def validate(self, obj, value):
# def get_from_nersc(user, relative_path):
# def rollback_and_log(db_connection, err):
# class NotifyList(list):
# class Workspace(object):
# class MetList(List):
# class MetUnicode(CUnicode):
# class MetFloat(CFloat):
# class MetInt(CInt):
# class MetBool(CBool):
# class Stub(HasTraits):
# class MetInstance(Instance):
# class MetEnum(Enum):


import getpass
import dill
from metatlas.datastructures import metatlas_objects as mo
from metatlas.datastructures import object_helpers as metoh

def test_store_stubs(sqlite):
    test = mo.Group(items=[mo.Group(items=[mo.LcmsRun()]), mo.LcmsRun()])
    mo.store(test)
    test = mo.retrieve("group", unique_id=test.unique_id)[0]
    assert isinstance(test.items[0], mo.Group)
    mo.store(test)


def test_user_preserve(sqlite):
    run = mo.LcmsRun(username="foo")
    test = mo.Reference(name="hello", username="foo", lcms_run=run)
    orig_id = test.unique_id
    mo.store(test, _override=True)
    assert test.unique_id == orig_id
    mo.store(test)
    assert test.unique_id != orig_id
    items = mo.retrieve("reference", username="*", name="hello")
    username = getpass.getuser()
    assert items[-2].username == "foo"
    assert items[-1].username == username
    assert items[-2].lcms_run.username == "foo"
    assert items[-1].lcms_run.username == "foo"


def test_store_all(sqlite):
    items = []
    for klass in metoh.Workspace.get_instance().subclass_lut.values():
        items.append(klass())
    mo.store(items)

# Path: metatlas/datastructures/metatlas_objects.py
# FETCH_STUBS = True
# ADDUCTS = ('','[M]+','[M+H]+','[M+H]2+','[M+2H]2+','[M+H-H2O]2+','[M+K]2+','[M+NH4]+','[M+Na]+','[M+H-H2O]+','[M-H]-','[M-2H]-','[M-H+Cl]-','[M-2H]2-','[M+Cl]-','[2M+H]+','[2M-H]-','[M-H+Na]+','[M+K]+','[M+2Na]2+','[M-e]+','[M+acetate]-','[M+formate]-','[M-H+Cl]2-','[M-H+2Na]+')
# POLARITY = ('positive', 'negative', 'alternating')
# FRAGMENTATION_TECHNIQUE = ('hcd','cid','etd','ecd','irmpd')
# ID_GRADES: Dict[str, IdentificationGrade] = dict()
#     FETCH_STUBS = False
#         FETCH_STUBS = True
#     FETCH_STUBS = True
# def retrieve(object_type, **kwargs):
# def remove(object_type, **kwargs):
# def remove_objects(objects, all_versions=True, **kwargs):
# def store(objects, **kwargs):
#     def __init__(self, **kwargs):
#     def _update(self, override_user=False):
#     def clone(self, recursive=False):
#     def show_diff(self, unique_id=None):
#     def _on_update(self, change):
#     def __str__(self):
#     def __repr__(self):
#     def __getattribute__(self, name):
#     def validate(self, obj, value):
# def find_invalid_runs(**kwargs):
# def to_dataframe(objects):
# class MetatlasObject(HasTraits):
# class Method(MetatlasObject):
# class Sample(MetatlasObject):
# class LcmsRun(MetatlasObject):
# class FunctionalSet(MetatlasObject):
# class Compound(MetatlasObject):
# class Reference(MetatlasObject):
# class IdentificationGrade(MetatlasObject):
# class _IdGradeTrait(MetInstance):
# class Group(MetatlasObject):
# class MzIntensityPair(MetatlasObject):
# class FragmentationReference(Reference):
# class RtReference(Reference):
# class MzReference(Reference):
# class IntensityReference(Reference):
# class CompoundIdentification(MetatlasObject):
# class Atlas(MetatlasObject):
# class MZMineTask(MetatlasObject):
# 
# Path: metatlas/datastructures/object_helpers.py
# ON_NERSC = 'METATLAS_LOCAL' not in os.environ
# def callback_method(func):
#     def notify(self, *args, **kwargs):
#     def __getitem__(self, item):
#     def __init__(self, *args):
#     def register_callback(self, cb):
#     def unregister_callback(self, cbid):
# def set_docstring(cls):
# def _get_subclasses(cls):
#     def __init__(self):
#     def get_instance(cls):
#     def get_connection(self):
#     def close_connection(self):
#     def convert_to_double(self, table, entry):
#     def save_objects(self, objects, _override=False):
#     def create_link_tables(self, klass):
#     def _get_save_data(self, obj, override=False):
#     def fix_table(self, table_name):
#     def retrieve(self, object_type, **kwargs):
#     def remove(self, object_type, **kwargs):
#     def remove_objects(self, objects, all_versions=True, **kwargs):
# def format_timestamp(tstamp):
#     def validate(self, obj, value):
#     def retrieve(self):
#     def __repr__(self):
#     def __str__(self):
#     def validate(self, obj, value):
# def get_from_nersc(user, relative_path):
# def rollback_and_log(db_connection, err):
# class NotifyList(list):
# class Workspace(object):
# class MetList(List):
# class MetUnicode(CUnicode):
# class MetFloat(CFloat):
# class MetInt(CInt):
# class MetBool(CBool):
# class Stub(HasTraits):
# class MetInstance(Instance):
# class MetEnum(Enum):


# Path: tests/unit/test_metatlas_objects.py
import getpass
import dill
from metatlas.datastructures import metatlas_objects as mo
from metatlas.datastructures import object_helpers as metoh


def test_store_stubs(sqlite):
    test = mo.Group(items=[mo.Group(items=[mo.LcmsRun()]), mo.LcmsRun()])
    mo.store(test)
    test = mo.retrieve("group", unique_id=test.unique_id)[0]
    assert isinstance(test.items[0], mo.Group)
    mo.store(test)


def test_user_preserve(sqlite):
    run = mo.LcmsRun(username="foo")
    test = mo.Reference(name="hello", username="foo", lcms_run=run)
    orig_id = test.unique_id
    mo.store(test, _override=True)
    assert test.unique_id == orig_id
    mo.store(test)
    assert test.unique_id != orig_id
    items = mo.retrieve("reference", username="*", name="hello")
    username = getpass.getuser()
    assert items[-2].username == "foo"
    assert items[-1].username == username
    assert items[-2].lcms_run.username == "foo"
    assert items[-1].lcms_run.username == "foo"


def test_store_all(sqlite):
    items = []
    for klass in metoh.Workspace.get_instance().subclass_lut.values():
        items.append(klass())
    mo.store(items)

    for klass in metoh.Workspace.get_instance().subclass_lut.values():