# Path: metatlas/io/metatlas_get_data_helper_fun.py
# def create_msms_dataframe(df):
# def compare_EIC_to_BPC_for_file(metatlas_dataset,file_index,yscale = 'linear'):
# def get_data_for_atlas_df_and_file(input_tuple):
# def get_bpc(filename,dataset='ms1_pos',integration='bpc'):
# def df_container_from_metatlas_file(my_file):
# def fast_nearest_interp(xi, x, y):
# def remove_ms1_data_not_in_atlas(atlas_df, data):
# def extract(data, ids, default=None):
# def set_nested(data, ids, value):
# def make_atlas_df(atlas):
# def transfer_identification_data_to_atlas(data, atlas, ids_list=None):
# def get_data_for_mzrt(row, data_df_pos, data_df_neg, extra_time=0.5, use_mz='mz', extra_mz=0.0):
# def get_ms1_summary(row):
# def get_ms2_data(row):
# def prefilter_ms1_dataframe_with_boundaries(data_df, rt_max, rt_min, mz_min, mz_max, extra_time=0.5, extra_mz=0.01):
# def get_ms1_eic(row):
# def retrieve_most_intense_msms_scan(data):
# def get_data_for_atlas_and_lcmsrun(atlas_df, df_container, extra_time, extra_mz):
#     def get_feature_data(atlas_df, pos_df, neg_df, use_mz='mz'):
# def get_ms2_dict(ms2_feature_data_df):
# def get_ms1_summary_data(ms1_feature_data_df):
# def get_eic_data(ms1_feature_data_df):
# def get_unique_scan_data(data):
# def get_non_redundant_precursor_list(prt,pmz,rt_cutoff,mz_cutoff):
# def organize_msms_scan_data(data,list_of_prt,list_of_pmz,list_of_pintensity):
# def get_data_for_a_compound(mz_ref,rt_ref,what_to_get,h5file,extra_time):
# def get_dill_data(fname):
# def get_group_names(data):
# def get_group_shortnames(data):
# def get_file_names(data,full_path=False):
# def get_compound_names(data,use_labels=False):
# def make_data_sources_tables(groups, myatlas, output_loc, polarity=None, overwrite=True):
#     D = defaultdict(list)
#     D = {k:v for k,v in D.items() if len(v)>1}
# 
# Path: metatlas/io/system_utils.py
# def send_mail(subject, username, body, force=False):
#     """Send the mail only once per day."""
# 
#     now = datetime.now()
#     if force or dtime(00, 00) <= now.time() <= dtime(00, 10):
#         sender = 'pasteur@nersc.gov'
#         receivers = [f"{username}@lbl.gov", "bpbowen@lbl.gov"]
#         message = """\
# From: %s
# To: %s
# Subject: %s
# 
# %s
#         """ % (sender, ", ".join(receivers), subject, body)
#         try:
#             smtpObj = smtplib.SMTP('smtp.lbl.gov')
#             smtpObj.sendmail(sender, receivers, message)
#             sys.stdout.write("Successfully sent email to %s\n" % username)
#             sys.stdout.flush()
#         except smtplib.SMTPException:
#             sys.stderr.write("Error: unable to send email to %s\n" % username)
#             sys.stdout.flush()


import smtplib
import mimetypes
import itertools
import time
import sys
import os
import glob
import pandas as pd
import metatlas.metatlas_objects.metatlas_objects as metob
import multiprocessing as mp
import numpy as np
from typing import Any, Dict
from datetime import datetime, time as dtime
from collections import defaultdict
from metatlas.io.mzml_loader import VERSION_TIMESTAMP
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
from subprocess import check_output
from metatlas.io import metatlas_get_data_helper_fun as ma_data
from metatlas.metatlas_objects.metatlas_objects import find_invalid_runs
from metatlas.io.system_utils import send_mail

std_name = 'ABMBA'
rt_max = -1
run_times: Dict[str, Any] = {}
save_path = '/project/projectdirs/metatlas/projects/istd_logs/'


def check_metatlas():
    """
    Checks for invalid runs.
    """
    invalid_runs = find_invalid_runs(_override=True)
    # Currently there exists a bug (?) where it shows empty files.
    # It could be a result of the database remembering invalid files
    # that were removed. Since there is no file associated with these runs,
    # there will not be any filename.
    # This can technically be fixed by running:
    # grouped = grouped.filter(False, str_list)
    # followed by a run to remove all usernames without any files,
    # but does not directly solve the problem.
    # Leaving this to someone in the future to resolve.
    if invalid_runs:
        grouped = defaultdict(list)
        for run in invalid_runs:
            grouped[run.username].append(run.mzml_file)
        for (username, filenames) in grouped.items():
            body = 'You have runs that are not longer accessible\n'
            body += 'To remove them from the database, run the following on ipython.nersc.gov:\n\n'
            body += 'from metatlas.metatlas_objects import find_invalid_runs, remove_objects\n'
            body += 'remove_objects(find_invalid_runs())\n\n'
            body += 'The invalid runs are:\n%s' % ('\n'.join(filenames))

# Path: metatlas/io/metatlas_get_data_helper_fun.py
# def create_msms_dataframe(df):
# def compare_EIC_to_BPC_for_file(metatlas_dataset,file_index,yscale = 'linear'):
# def get_data_for_atlas_df_and_file(input_tuple):
# def get_bpc(filename,dataset='ms1_pos',integration='bpc'):
# def df_container_from_metatlas_file(my_file):
# def fast_nearest_interp(xi, x, y):
# def remove_ms1_data_not_in_atlas(atlas_df, data):
# def extract(data, ids, default=None):
# def set_nested(data, ids, value):
# def make_atlas_df(atlas):
# def transfer_identification_data_to_atlas(data, atlas, ids_list=None):
# def get_data_for_mzrt(row, data_df_pos, data_df_neg, extra_time=0.5, use_mz='mz', extra_mz=0.0):
# def get_ms1_summary(row):
# def get_ms2_data(row):
# def prefilter_ms1_dataframe_with_boundaries(data_df, rt_max, rt_min, mz_min, mz_max, extra_time=0.5, extra_mz=0.01):
# def get_ms1_eic(row):
# def retrieve_most_intense_msms_scan(data):
# def get_data_for_atlas_and_lcmsrun(atlas_df, df_container, extra_time, extra_mz):
#     def get_feature_data(atlas_df, pos_df, neg_df, use_mz='mz'):
# def get_ms2_dict(ms2_feature_data_df):
# def get_ms1_summary_data(ms1_feature_data_df):
# def get_eic_data(ms1_feature_data_df):
# def get_unique_scan_data(data):
# def get_non_redundant_precursor_list(prt,pmz,rt_cutoff,mz_cutoff):
# def organize_msms_scan_data(data,list_of_prt,list_of_pmz,list_of_pintensity):
# def get_data_for_a_compound(mz_ref,rt_ref,what_to_get,h5file,extra_time):
# def get_dill_data(fname):
# def get_group_names(data):
# def get_group_shortnames(data):
# def get_file_names(data,full_path=False):
# def get_compound_names(data,use_labels=False):
# def make_data_sources_tables(groups, myatlas, output_loc, polarity=None, overwrite=True):
#     D = defaultdict(list)
#     D = {k:v for k,v in D.items() if len(v)>1}
# 
# Path: metatlas/io/system_utils.py
# def send_mail(subject, username, body, force=False):
#     """Send the mail only once per day."""
# 
#     now = datetime.now()
#     if force or dtime(00, 00) <= now.time() <= dtime(00, 10):
#         sender = 'pasteur@nersc.gov'
#         receivers = [f"{username}@lbl.gov", "bpbowen@lbl.gov"]
#         message = """\
# From: %s
# To: %s
# Subject: %s
# 
# %s
#         """ % (sender, ", ".join(receivers), subject, body)
#         try:
#             smtpObj = smtplib.SMTP('smtp.lbl.gov')
#             smtpObj.sendmail(sender, receivers, message)
#             sys.stdout.write("Successfully sent email to %s\n" % username)
#             sys.stdout.flush()
#         except smtplib.SMTPException:
#             sys.stderr.write("Error: unable to send email to %s\n" % username)
#             sys.stdout.flush()


# Path: metatlas/io/integrity_monitor.py
import smtplib
import mimetypes
import itertools
import time
import sys
import os
import glob
import pandas as pd
import metatlas.metatlas_objects.metatlas_objects as metob
import multiprocessing as mp
import numpy as np
from typing import Any, Dict
from datetime import datetime, time as dtime
from collections import defaultdict
from metatlas.io.mzml_loader import VERSION_TIMESTAMP
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
from subprocess import check_output
from metatlas.io import metatlas_get_data_helper_fun as ma_data
from metatlas.metatlas_objects.metatlas_objects import find_invalid_runs
from metatlas.io.system_utils import send_mail

std_name = 'ABMBA'
rt_max = -1
run_times: Dict[str, Any] = {}
save_path = '/project/projectdirs/metatlas/projects/istd_logs/'


def check_metatlas():
    """
    Checks for invalid runs.
    """
    invalid_runs = find_invalid_runs(_override=True)
    # Currently there exists a bug (?) where it shows empty files.
    # It could be a result of the database remembering invalid files
    # that were removed. Since there is no file associated with these runs,
    # there will not be any filename.
    # This can technically be fixed by running:
    # grouped = grouped.filter(False, str_list)
    # followed by a run to remove all usernames without any files,
    # but does not directly solve the problem.
    # Leaving this to someone in the future to resolve.
    if invalid_runs:
        grouped = defaultdict(list)
        for run in invalid_runs:
            grouped[run.username].append(run.mzml_file)
        for (username, filenames) in grouped.items():
            body = 'You have runs that are not longer accessible\n'
            body += 'To remove them from the database, run the following on ipython.nersc.gov:\n\n'
            body += 'from metatlas.metatlas_objects import find_invalid_runs, remove_objects\n'
            body += 'remove_objects(find_invalid_runs())\n\n'
            body += 'The invalid runs are:\n%s' % ('\n'.join(filenames))

            send_mail('Metatlas Runs are Invalid', username, body)
