#!/bin/python
## MISTIC Project INRIA/INRAE
## Author Muller Coralie
## Date: 2025/08/19
## Update: 2025/10/31

"""
Description:
Test mapping: Test the results generated by the main function mapping_run, with the final results datatable for each option
    - Classic
    - Classic with partial option
    - Community
    - Community with partial option
"""
import csv
from os import path
from pathlib import Path
from metanetmap import mapping


#------------------------------------#
#        DIRECTORIES AND FILES       #
#------------------------------------#
TEST_TOYS_DIR = Path(__file__).parent.parent
TEST_EXPECTED_DIR = Path(__file__).parent


DATATABLE_CONVERSION = path.join(TEST_TOYS_DIR,'src/metanetmap/toys_tests_data/conversion_datatable_toys.tsv')
SBML_FILE_INPUT = path.join(TEST_TOYS_DIR,"src/metanetmap/toys_tests_data/toys/sbml/toys2.sbml")
MAF_DIR_INPUT = path.join(TEST_TOYS_DIR,"src/metanetmap/toys_tests_data/toys/maf/")
SBML_DIR_INPUT = path.join(TEST_TOYS_DIR,"src/metanetmap/toys_tests_data/toys/sbml/")

#Temporary 
MAF_DIR_TOYS1 = path.join(TEST_TOYS_DIR,"src/metanetmap/toys_tests_data/toys/maf/toys1.tsv")
MAF_DIR_TOYS2 = path.join(TEST_TOYS_DIR,"src/metanetmap/toys_tests_data/toys/maf/toys2.tsv")
MAF_DIR_TOYS3 = path.join(TEST_TOYS_DIR,"src/metanetmap/toys_tests_data/toys/maf/toys3.tsv")
SBML_DIR_TOYS1 = path.join(TEST_TOYS_DIR,"src/metanetmap/toys_tests_data/toys/sbml/toys1.sbml")
SBML_DIR_TOYS2 = path.join(TEST_TOYS_DIR,"src/metanetmap/toys_tests_data/toys/sbml/toys2.sbml")
SBML_DIR_TOYS3 = path.join(TEST_TOYS_DIR,"src/metanetmap/toys_tests_data/toys/sbml/toys3.xml")

#Timer
START_TIME_PARTIAL = "XXXX-XX-XX_XX_XX_50"
START_TIME = "XXXX-XX-XX_XX_XX_48"
TIMESTAMP= "1694872984.472839"

#Expected final files
EXPECTED_FILE_COMMUNITY= path.join(TEST_EXPECTED_DIR,"expected_results/community_mapping_results_2025-10-27_15_51_33.tsv") 
EXPECTED_FILE_COMMUNITY_PARTIAL= path.join(TEST_EXPECTED_DIR,"expected_results/community_mapping_results_partial_match_2025-10-27_15_55_35.tsv") 
EXPECTED_FILE_CLASSIC= path.join(TEST_EXPECTED_DIR,"expected_results/t2mapping_results_2025-10-27_15_35_48.tsv") 
EXPECTED_FILE_CLASSIC_PARTIAL= path.join(TEST_EXPECTED_DIR,"expected_results/t2mapping_results_partial_match_2025-10-27_15_36_16.tsv") 

#Output:
OUTPUT_FILENAME_CLASSIC = f"mapping_results_{START_TIME}.tsv"
OUTPUT_FILENAME_CLASSIC_P = f"mapping_results_partial_match_{START_TIME_PARTIAL}.tsv"
OUTPUT_FILENAME_COMM = f"community_mapping_results_{START_TIME}.tsv"
OUTPUT_FILENAME_COMM_P = f"community_mapping_results_partial_match_{START_TIME_PARTIAL}.tsv"




# ----------------------------------------------------------


#---------------------------------#
#         FIXED VARIABLES         #
#---------------------------------#
PARTIAL_MODE=True
NO_PARTIAL=False
COMMUNITY_MODE="community"
QUIET_MODE=False
# ----------------------------------------------------------

#utils
def read_tsv(fp):
    with open(fp, encoding='utf-8') as f:
        return sorted(list(csv.DictReader(f, delimiter='\t')), key=lambda x: str(x))
    

# ----------------------------------------------------------

#------------------------------#
#         General TESTS         #
#------------------------------#


#### Results table
def test_mapping_run_vs_expected_classic(tmp_path):
    # 1. Settings
    output_folder = tmp_path
    output_folder.mkdir(parents=True, exist_ok=True)  
    output_path=output_folder/OUTPUT_FILENAME_CLASSIC


    # 2. Load input data
    dictionary_db = mapping.load_database(DATATABLE_CONVERSION)
    List_MAF_paths = mapping.set_list_paths(MAF_DIR_INPUT, [], ext1=None, ext2=None)
    List_SBML_paths = mapping.set_list_paths(SBML_FILE_INPUT, [], '.sbml', '.xml')
    maf_dictionnary, keys, maf_df = mapping.setup_merged_list_maf_metabolites(List_MAF_paths)
    dic_couple_sbml, meta_data_sbml = mapping.setup_merge_list_sbml_metabolites(List_SBML_paths)

    
    # 3. Run the mapping
    mapping.mapping_run(
        output_folder=output_folder,
        dictionary_db=dictionary_db,
        maf_dictionnary=maf_dictionnary,
        keys=keys,
        maf_df=maf_df,
        meta_data_sbml=meta_data_sbml,
        dic_couple_sbml=dic_couple_sbml,
        start_time=START_TIME,
        partial_match=NO_PARTIAL,
        quiet=QUIET_MODE,
        timestamp=TIMESTAMP,
        choice=None
    )

    # 4. Check the generated file
    assert output_path.exists(), "Output file not generated"

    # 5.  Compare contents
    actual = read_tsv(output_path)
    expected = read_tsv(EXPECTED_FILE_CLASSIC)

    assert actual == expected, "The generated table does not match the expected one"




def test_mapping_run_vs_expected_classic_partial(tmp_path):
    # 1. Settings
    output_folder = tmp_path
    output_folder.mkdir(parents=True, exist_ok=True)  
    output_path=output_folder/OUTPUT_FILENAME_CLASSIC_P


    # 2. Load input data
    dictionary_db = mapping.load_database(DATATABLE_CONVERSION)
    List_MAF_paths = mapping.set_list_paths(MAF_DIR_INPUT, [], ext1=None, ext2=None)
    List_SBML_paths = mapping.set_list_paths(SBML_FILE_INPUT, [], '.sbml', '.xml')
    maf_dictionnary, keys, maf_df = mapping.setup_merged_list_maf_metabolites(List_MAF_paths)
    dic_couple_sbml, meta_data_sbml = mapping.setup_merge_list_sbml_metabolites(List_SBML_paths)

    # 3. Run the mapping
    mapping.mapping_run(
        output_folder=output_folder,
        dictionary_db=dictionary_db,
        maf_dictionnary=maf_dictionnary,
        keys=keys,
        maf_df=maf_df,
        meta_data_sbml=meta_data_sbml,
        dic_couple_sbml=dic_couple_sbml,
        start_time=START_TIME_PARTIAL,
        partial_match=PARTIAL_MODE,
        quiet=QUIET_MODE,
        timestamp=TIMESTAMP,
        choice=None
    )

    # 4. Check the generated file
    assert output_path.exists(), "Output file not generated"

    # 5. Compare contents
    actual = read_tsv(output_path)
    expected = read_tsv(EXPECTED_FILE_CLASSIC_PARTIAL)

    assert actual == expected, "The generated table does not match the expected one"




def test_mapping_run_vs_expected_community(tmp_path):
    # 1. Settings
    output_folder = tmp_path
    output_folder.mkdir(parents=True, exist_ok=True)  
    output_path=output_folder/OUTPUT_FILENAME_COMM


    # 2. Load input data
    dictionary_db = mapping.load_database(DATATABLE_CONVERSION)
    # List_MAF_paths = mapping.set_list_paths(MAF_DIR_INPUT, [], ext1=None, ext2=None)
    # List_SBML_paths = mapping.set_list_paths(SBML_DIR_INPUT, [], '.sbml', '.xml')
    List_MAF_paths = [MAF_DIR_TOYS1, MAF_DIR_TOYS3, MAF_DIR_TOYS2]
    List_SBML_paths = [SBML_DIR_TOYS1, SBML_DIR_TOYS3, SBML_DIR_TOYS2]
    maf_dictionnary, keys, maf_df = mapping.setup_merged_list_maf_metabolites(List_MAF_paths)
    dic_couple_sbml, meta_data_sbml = mapping.setup_merge_list_sbml_metabolites(List_SBML_paths)

    # 3. Run the mapping
    mapping.mapping_run(
        output_folder=output_folder,
        dictionary_db=dictionary_db,
        maf_dictionnary=maf_dictionnary,
        keys=keys,
        maf_df=maf_df,
        meta_data_sbml=meta_data_sbml,
        dic_couple_sbml=dic_couple_sbml,
        start_time=START_TIME,
        partial_match=NO_PARTIAL,
        quiet=QUIET_MODE,
        timestamp=TIMESTAMP,
        choice=COMMUNITY_MODE
    )

    # 4. Check the generated file
    assert output_path.exists(), "Output file not generated"

    # 5. Compare contents
    actual = read_tsv(output_path)
    expected = read_tsv(EXPECTED_FILE_COMMUNITY)
    assert actual == expected, "The generated table does not match the expected one"



def test_mapping_run_vs_expected_community_partial(tmp_path):
    # 1. Settings
    output_folder = tmp_path
    output_folder.mkdir(parents=True, exist_ok=True)  
    output_path=output_folder/OUTPUT_FILENAME_COMM_P


    # 2. Load input data
    dictionary_db = mapping.load_database(DATATABLE_CONVERSION)
    # List_MAF_paths = mapping.set_list_paths(MAF_DIR_INPUT, [], ext1=None, ext2=None)
    # List_SBML_paths = mapping.set_list_paths(SBML_DIR_INPUT, [], '.sbml', '.xml')
    List_MAF_paths = [MAF_DIR_TOYS1, MAF_DIR_TOYS3, MAF_DIR_TOYS2]
    List_SBML_paths = [SBML_DIR_TOYS1, SBML_DIR_TOYS3, SBML_DIR_TOYS2]
    maf_dictionnary, keys, maf_df = mapping.setup_merged_list_maf_metabolites(List_MAF_paths)
    dic_couple_sbml, meta_data_sbml = mapping.setup_merge_list_sbml_metabolites(List_SBML_paths)

    # 3. Run the mapping
    mapping.mapping_run(
        output_folder=output_folder,
        dictionary_db=dictionary_db,
        maf_dictionnary=maf_dictionnary,
        keys=keys,
        maf_df=maf_df,
        meta_data_sbml=meta_data_sbml,
        dic_couple_sbml=dic_couple_sbml,
        start_time=START_TIME_PARTIAL,
        partial_match=PARTIAL_MODE,
        quiet=QUIET_MODE,
        timestamp=TIMESTAMP,
        choice=COMMUNITY_MODE
    )

    # 4. Check the generated file
    assert output_path.exists(), "Output file not generated"

    # 5. Compare contents
    actual = read_tsv(output_path)
    expected = read_tsv(EXPECTED_FILE_COMMUNITY_PARTIAL)
    assert actual == expected, "The generated table does not match the expected one"


