from deepdiff import DeepDiff

from SAF.features.generator import compute_quaternary_features


def test_generate_features():
    file_path = "tests/cif/quaternary/Tb4RhInGe4.cif"
    actual_features, actual_uni_features = compute_quaternary_features(file_path)
    expected_features = {
        "Entry": "Tb4RhInGe4",
        "Formula": "Tb4RhInGe4",
        "Structure": "Tb4RhInGe4",
        "A": "Tb",
        "B": "Rh",
        "C": "In",
        "D": "Ge",
        "INT_AA_dist": 3.538,
        "INT_BB_dist": 3.148,
        "INT_CC_dist": 4.264,
        "INT_DD_dist": 2.596,
        "INT_AB_dist": 3.076,
        "INT_AC_dist": 3.367,
        "INT_AD_dist": 2.917,
        "INT_BC_dist": 4.711,
        "INT_BD_dist": 2.47,
        "INT_CD_dist": 2.818,
        "INT_Asize": 1.764,
        "INT_Bsize": 1.345,
        "INT_Csize": 1.624,
        "INT_Dsize": 1.225,
        "INT_Asize_by_Bsize": 1.3115241635687733,
        "INT_Bsize_by_Csize": 0.8282019704433496,
        "INT_Csize_by_Dsize": 1.3257142857142856,
        "INT_Asize_by_Csize": 1.086206896551724,
        "INT_Asize_by_Dsize": 1.44,
        "INT_Bsize_by_Dsize": 1.0979591836734692,
        "INT_AA_dist_by_2_by_Asize": 1.0028344671201814,
        "INT_BB_dist_by_2_by_Bsize": 1.1702602230483272,
        "INT_CC_dist_by_2_by_Csize": 1.312807881773399,
        "INT_DD_dist_by_2_by_Dsize": 1.059591836734694,
        "INT_AB_dist_by_ABsizes": 0.9893856545513027,
        "INT_AC_dist_by_ACsizes": 0.9938016528925621,
        "INT_AD_dist_by_ADsizes": 0.9759116761458682,
        "INT_BC_dist_by_BCsizes": 1.5867295385651734,
        "INT_BD_dist_by_BDsizes": 0.961089494163424,
        "INT_CD_dist_by_CDsizes": 0.9891189891189891,
        "INT_Asize_ref": 1.6862073857087099,
        "INT_Bsize_ref": 1.4201916565448087,
        "INT_Csize_ref": 1.6861073857088038,
        "INT_Dsize_ref": 1.1604492903475334,
        "INT_percent_diff_A_by_100": -0.04410012148032321,
        "INT_percent_diff_B_by_100": 0.05590457735673513,
        "INT_percent_diff_C_by_100": 0.038243464106406215,
        "INT_percent_diff_D_by_100": -0.05269445685915647,
        "INT_AA_minus_ref_diff": 0.04680193006856418,
        "INT_BB_minus_ref_diff": 0.0977181343425612,
        "INT_CC_minus_ref_diff": 0.20914287724727781,
        "INT_DD_minus_ref_diff": 0.10597127091869539,
        "INT_AB_minus_ref_diff": -0.009882653528452056,
        "INT_AC_minus_ref_diff": -0.0015784886894902542,
        "INT_AD_minus_ref_diff": 0.02411495507156549,
        "INT_BC_minus_ref_diff": 0.3406285200056013,
        "INT_BD_minus_ref_diff": -0.04479390562442993,
        "INT_CD_minus_ref_diff": -0.010133667869530575,
        "INT_R_factor": 0.00930941081455393,
        "INT_UNI_shortest_homoatomic_dist": 2.596,
        "INT_UNI_shortest_heteroatomic_dist": 2.47,
        "INT_UNI_shortest_homoatomic_dist_by_2_by_atom_size": 1.059591836734694,
        "INT_UNI_shortest_heteroatomic_dist_by_sum_of_atom_sizes": 0.961089494163424,
        "INT_UNI_shortest_homoatomic_dist_by_2_by_refined_atom_size": 1.1185322881375306,
        "INT_UNI_shortest_heteroatomic_dist_by_sum_of_refined_atom_sizes": 0.9571265630634986,
        "INT_UNI_highest_refined_percent_diff_abs": 0.05590457735673513,
        "INT_UNI_lowest_refined_percent_diff_abs": 0.038243464106406215,
        "INT_UNI_refined_packing_efficiency": 0.6486230122109067,
        "WYK_A_lowest_wyckoff": 4,
        "WYK_B_lowest_wyckoff": 4,
        "WYK_C_lowest_wyckoff": 2,
        "WYK_D_lowest_wyckoff": 4,
        "WYK_identical_lowest_wyckoff_count": 1,
        "WYK_A_sites_total": 4,
        "WYK_B_sites_total": 1,
        "WYK_C_sites_total": 2,
        "WYK_D_sites_total": 4,
        "WYK_A_multiplicity_total": 16,
        "WYK_B_multiplicity_total": 4,
        "WYK_C_multiplicity_total": 4,
        "WYK_D_multiplicity_total": 16,
        "ENV_A_shortest_dist_count": 1,
        "ENV_B_shortest_dist_count": 2,
        "ENV_C_shortest_dist_count": 2,
        "ENV_D_shortest_dist_count": 2,
        "ENV_A_avg_shortest_dist_count": 1.75,
        "ENV_B_avg_shortest_dist_count": 2.0,
        "ENV_C_avg_shortest_dist_count": 2.0,
        "ENV_D_avg_shortest_dist_count": 1.25,
        "ENV_A_shortest_tol_dist_count": 6,
        "ENV_B_shortest_tol_dist_count": 4,
        "ENV_C_shortest_tol_dist_count": 4,
        "ENV_D_shortest_tol_dist_count": 3,
        "ENV_A_avg_shortest_dist_within_tol_count": 5.0,
        "ENV_B_avg_shortest_dist_within_tol_count": 4.0,
        "ENV_C_avg_shortest_dist_within_tol_count": 3.0,
        "ENV_D_avg_shortest_dist_within_tol_count": 1.75,
        "ENV_A_second_by_first_shortest_dist": 1.0205690778196779,
        "ENV_B_second_by_first_shortest_dist": 1.0291497975708501,
        "ENV_C_second_by_first_shortest_dist": 1.0184528034066713,
        "ENV_D_second_by_first_shortest_dist": 1.0291497975708501,
        "ENV_A_avg_second_by_first_shortest_dist": 1.0364821721769375,
        "ENV_B_avg_second_by_first_shortest_dist": 1.0291497975708501,
        "ENV_C_avg_second_by_first_shortest_dist": 1.0440696072782485,
        "ENV_D_avg_second_by_first_shortest_dist": 1.0680669343726787,
        "ENV_A_second_shortest_dist_count": 2,
        "EnV_B_second_shortest_dist_count": 1,
        "ENV_C_second_shortest_dist_count": 2,
        "ENV_D_second_shortest_dist_count": 1,
        "ENV_A_avg_second_shortest_dist_count": 2.0,
        "ENV_B_avg_second_shortest_dist_count": 1.0,
        "ENV_C_avg_second_shortest_dist_count": 2.0,
        "ENV_D_avg_second_shortest_dist_count": 1.25,
        "ENV_A_homoatomic_dist_by_shortest_dist": 1.2128899554336647,
        "ENV_B_homoatomic_dist_by_shortest_dist": 1.274493927125506,
        "ENV_C_homoatomic_dist_by_shortest_dist": 1.5131298793470547,
        "ENV_D_homoatomic_dist_by_shortest_dist": 1.0510121457489878,
        "ENV_A_avg_homoatomic_dist_by_shortest_dist": 1.215032553686275,
        "ENV_B_avg_homoatomic_dist_by_shortest_dist": 1.274493927125506,
        "ENV_C_avg_homoatomic_dist_by_shortest_dist": 1.4994220825306703,
        "ENV_D_avg_homoatomic_dist_by_shortest_dist": 1.0193165160610715,
        "ENV_A_count_at_A_shortest_dist": 0,
        "ENV_B_count_at_A_shortest_dist": 0,
        "ENV_C_count_at_A_shortest_dist": 0,
        "ENV_D_count_at_A_shortest_dist": 1,
        "ENV_A_avg_count_at_A_shortest_dist": 0.0,
        "ENV_B_avg_count_at_A_shortest_dist": 0.0,
        "ENV_C_avg_count_at_A_shortest_dist": 0.0,
        "ENV_D_avg_count_at_A_shortest_dist": 1.75,
        "ENV_A_count_at_B_shortest_dist": 0,
        "ENV_B_count_at_B_shortest_dist": 0,
        "ENV_C_count_at_B_shortest_dist": 0,
        "ENV_D_count_at_B_shortest_dist": 2,
        "ENV_A_avg_count_at_B_shortest_dist": 0.0,
        "ENV_B_avg_count_at_B_shortest_dist": 0.0,
        "ENV_C_avg_count_at_B_shortest_dist": 0.0,
        "ENV_D_avg_count_at_B_shortest_dist": 2.0,
        "ENV_A_count_at_C_shortest_dist": 0,
        "ENV_B_count_at_C_shortest_dist": 0,
        "ENV_C_count_at_C_shortest_dist": 0,
        "ENV_D_count_at_C_shortest_dist": 2,
        "ENV_A_avg_count_at_C_shortest_dist": 0.0,
        "ENV_B_avg_count_at_C_shortest_dist": 0.0,
        "ENV_C_avg_count_at_C_shortest_dist": 0.0,
        "ENV_D_avg_count_at_C_shortest_dist": 2.0,
        "ENV_A_count_at_D_shortest_dist": 0,
        "ENV_B_count_at_D_shortest_dist": 2,
        "ENV_C_count_at_D_shortest_dist": 0,
        "ENV_D_count_at_D_shortest_dist": 0,
        "ENV_A_avg_count_at_D_shortest_dist": 0.0,
        "ENV_B_avg_count_at_D_shortest_dist": 0.75,
        "ENV_C_avg_count_at_D_shortest_dist": 0.0,
        "ENV_D_avg_count_at_D_shortest_dist": 0.5,
        "CN_AVG_coordination_number": 13.068181818181818,
        "CN_AVG_A_atom_count": 6.9772727272727275,
        "CN_AVG_B_atom_count": 1.0909090909090908,
        "CN_AVG_C_atom_count": 1.2727272727272727,
        "CN_AVG_D_atom_count": 3.727272727272727,
        "CN_AVG_polyhedron_volume": 85.2066590909091,
        "CN_AVG_central_atom_to_center_of_mass_dist": 0.09586363636363636,
        "CN_AVG_number_of_edges": 33.20454545454545,
        "CN_AVG_number_of_faces": 22.136363636363637,
        "CN_AVG_shortest_distance_to_face": 2.3237954545454547,
        "CN_AVG_shortest_distance_to_edge": 2.3122045454545455,
        "CN_AVG_volume_of_inscribed_sphere": 56.64554545454546,
        "CN_AVG_packing_efficiency": 0.6419318181818182,
        "CN_MIN_coordination_number": 12.818181818181818,
        "CN_MIN_A_atom_count": 6.909090909090909,
        "CN_MIN_B_atom_count": 1.0909090909090908,
        "CN_MIN_C_atom_count": 1.0909090909090908,
        "CN_MIN_D_atom_count": 3.727272727272727,
        "CN_MIN_polyhedron_volume": 82.8599090909091,
        "CN_MIN_central_atom_to_center_of_mass_dist": 0.09072727272727273,
        "CN_MIN_number_of_edges": 32.45454545454545,
        "CN_MIN_number_of_faces": 21.636363636363637,
        "CN_MIN_shortest_distance_to_face": 2.266909090909091,
        "CN_MIN_shortest_distance_to_edge": 2.220272727272728,
        "CN_MIN_volume_of_inscribed_sphere": 53.95327272727274,
        "CN_MIN_packing_efficiency": 0.6151818181818182,
        "CN_MAX_coordination_number": 13.272727272727273,
        "CN_MAX_A_atom_count": 7.0,
        "CN_MAX_B_atom_count": 1.0909090909090908,
        "CN_MAX_C_atom_count": 1.4545454545454546,
        "CN_MAX_D_atom_count": 3.727272727272727,
        "CN_MAX_polyhedron_volume": 87.19890909090908,
        "CN_MAX_central_atom_to_center_of_mass_dist": 0.11127272727272727,
        "CN_MAX_number_of_edges": 33.81818181818182,
        "CN_MAX_number_of_faces": 22.545454545454547,
        "CN_MAX_shortest_distance_to_face": 2.3538181818181814,
        "CN_MAX_shortest_distance_to_edge": 2.3721818181818186,
        "CN_MAX_volume_of_inscribed_sphere": 58.341636363636354,
        "CN_MAX_packing_efficiency": 0.6512727272727273,
    }
    # FIXME: This tolernace is too high because the polyhedron volume constantly changes
    diff = DeepDiff(expected_features, actual_features, math_epsilon=1)
    assert diff == {}
    expected_uni_features = {
        "Entry": "Tb4RhInGe4",
        "Formula": "Tb4RhInGe4",
        "INT_UNI_shortest_homoatomic_dist": 2.596,
        "INT_UNI_shortest_heteroatomic_dist": 2.47,
        "INT_UNI_shortest_homoatomic_dist_by_2_by_atom_size": 1.059591836734694,
        "INT_UNI_shortest_heteroatomic_dist_by_sum_of_atom_sizes": 0.961089494163424,
        "INT_UNI_shortest_homoatomic_dist_by_2_by_refined_atom_size": 1.1185322881375306,
        "INT_UNI_shortest_heteroatomic_dist_by_sum_of_refined_atom_sizes": 0.9571265630634986,
        "INT_UNI_highest_refined_percent_diff_abs": 0.05590457735673513,
        "INT_UNI_lowest_refined_percent_diff_abs": 0.038243464106406215,
        "INT_UNI_refined_packing_efficiency": 0.6486230122109067,
        "UNI_WYK_lowest_wyckoff": 2,
    }
    diff = DeepDiff(expected_uni_features, actual_uni_features, math_epsilon=1)
    assert diff == {}
