from deepdiff import DeepDiff

from CAF.features.universal import generate_features


def test_generate_features_ternary(oliynyk_db):
    formula = "OsSn5Co2"
    actual_features = generate_features(formula, oliynyk_db)
    expected_features = {
        "formula": "OsSn5Co2",
        "index_norm_first_element": 0.125,
        "index_norm_last_element": 0.25,
        "index_norm_max": 0.625,
        "index_norm_min": 0.125,
        "num_element": 3,
        "atomic_weight_avg_weighted_norm": 112.7058,
        "atomic_weight_avg": 122.6244,
        "atomic_weight_max": 190.23,
        "atomic_weight_min": 58.9332,
        "atomic_weight_max_by_min": 3.2278919183075074,
        "atomic_weight_first_element": 190.23,
        "atomic_weight_last_element": 58.9332,
        "atomic_number_avg_weighted_norm": 47.5,
        "atomic_number_avg": 51.0,
        "atomic_number_max": 76,
        "atomic_number_min": 27,
        "atomic_number_max_by_min": 2.814814814814815,
        "atomic_number_first_element": 76,
        "atomic_number_last_element": 27,
        "group_avg_weighted_norm": 12.0,
        "group_avg": 10.333333333333334,
        "group_max": 14,
        "group_min": 8,
        "group_max_by_min": 1.75,
        "group_first_element": 8,
        "group_last_element": 9,
        "period_avg_weighted_norm": 4.875,
        "period_avg": 5.0,
        "period_max": 6,
        "period_min": 4,
        "period_max_by_min": 1.5,
        "period_first_element": 6,
        "period_last_element": 4,
        "Mendeleev_number_avg_weighted_norm": 71.625,
        "Mendeleev_number_avg": 65.0,
        "Mendeleev_number_max": 80,
        "Mendeleev_number_min": 57,
        "Mendeleev_number_max_by_min": 1.4035087719298245,
        "Mendeleev_number_first_element": 57,
        "Mendeleev_number_last_element": 58,
        "valencee_total_avg_weighted_norm": 12.0,
        "valencee_total_avg": 10.333333333333334,
        "valencee_total_max": 14,
        "valencee_total_min": 8,
        "valencee_total_max_by_min": 1.75,
        "valencee_total_first_element": 8,
        "valencee_total_last_element": 9,
        "unpaired_electrons_avg_weighted_norm": 2.5,
        "unpaired_electrons_avg": 3.0,
        "unpaired_electrons_max": 4,
        "unpaired_electrons_min": 2,
        "unpaired_electrons_max_by_min": 2.0,
        "unpaired_electrons_first_element": 4,
        "unpaired_electrons_last_element": 3,
        "Gilman_avg_weighted_norm": 4.125,
        "Gilman_avg": 4.333333333333333,
        "Gilman_max": 5,
        "Gilman_min": 4,
        "Gilman_max_by_min": 1.25,
        "Gilman_first_element": 5,
        "Gilman_last_element": 4,
        "Z_eff_avg_weighted_norm": 3.7624999999999997,
        "Z_eff_avg": 4.122,
        "Z_eff_max": 5.648,
        "Z_eff_min": 3.046,
        "Z_eff_max_by_min": 1.8542350623768877,
        "Z_eff_first_element": 5.648,
        "Z_eff_last_element": 3.046,
        "ionization_energy_avg_weighted_norm": 7.6149625,
        "ionization_energy_avg": 7.8877,
        "ionization_energy_max": 8.4382,
        "ionization_energy_min": 7.3439,
        "ionization_energy_max_by_min": 1.149008020261714,
        "ionization_energy_first_element": 8.4382,
        "ionization_energy_last_element": 7.881,
        "coordination_number_avg_weighted_norm": 8.25,
        "coordination_number_avg": 10.0,
        "coordination_number_max": 12,
        "coordination_number_min": 6,
        "coordination_number_max_by_min": 2.0,
        "coordination_number_first_element": 12,
        "coordination_number_last_element": 12,
        "ratio_closest_avg_weighted_norm": 0.6041666666666666,
        "ratio_closest_avg": 0.5555555555555555,
        "ratio_closest_max": 0.6666666666666666,
        "ratio_closest_min": 0.5,
        "ratio_closest_max_by_min": 1.3333333333333333,
        "ratio_closest_first_element": 0.5,
        "ratio_closest_last_element": 0.5,
        "polyhedron_distortion_avg_weighted_norm": 0.964375,
        "polyhedron_distortion_avg": 0.9743333333333334,
        "polyhedron_distortion_max": 0.996,
        "polyhedron_distortion_min": 0.949,
        "polyhedron_distortion_max_by_min": 1.0495258166491044,
        "polyhedron_distortion_first_element": 0.978,
        "polyhedron_distortion_last_element": 0.996,
        "CIF_radius_avg_weighted_norm": 1.424,
        "CIF_radius_avg": 1.3659999999999999,
        "CIF_radius_max": 1.511,
        "CIF_radius_min": 1.25,
        "CIF_radius_max_by_min": 1.2087999999999999,
        "CIF_radius_first_element": 1.337,
        "CIF_radius_last_element": 1.25,
        "Pauling_radius_CN12_avg_weighted_norm": 1.49425,
        "Pauling_radius_CN12_avg": 1.4073333333333335,
        "Pauling_radius_CN12_max": 1.62,
        "Pauling_radius_CN12_min": 1.252,
        "Pauling_radius_CN12_max_by_min": 1.293929712460064,
        "Pauling_radius_CN12_first_element": 1.35,
        "Pauling_radius_CN12_last_element": 1.252,
        "Pauling_EN_avg_weighted_norm": 1.9700000000000002,
        "Pauling_EN_avg": 2.013333333333333,
        "Pauling_EN_max": 2.2,
        "Pauling_EN_min": 1.88,
        "Pauling_EN_max_by_min": 1.170212765957447,
        "Pauling_EN_first_element": 2.2,
        "Pauling_EN_last_element": 1.88,
        "Martynov_Batsanov_EN_avg_weighted_norm": 1.8362499999999997,
        "Martynov_Batsanov_EN_avg": 1.8166666666666667,
        "Martynov_Batsanov_EN_max": 1.88,
        "Martynov_Batsanov_EN_min": 1.72,
        "Martynov_Batsanov_EN_max_by_min": 1.0930232558139534,
        "Martynov_Batsanov_EN_first_element": 1.85,
        "Martynov_Batsanov_EN_last_element": 1.72,
        "melting_point_K_avg_weighted_norm": 1172.525,
        "melting_point_K_avg": 1863.8166666666666,
        "melting_point_K_max": 3318.15,
        "melting_point_K_min": 505.15,
        "melting_point_K_max_by_min": 6.568642977333465,
        "melting_point_K_first_element": 3318.15,
        "melting_point_K_last_element": 1768.15,
        "density_avg_weighted_norm": 9.61875,
        "density_avg": 12.936666666666667,
        "density_max": 22.6,
        "density_min": 7.31,
        "density_max_by_min": 3.0916552667578663,
        "density_first_element": 22.6,
        "density_last_element": 8.9,
        "specific_heat_avg_weighted_norm": 0.263125,
        "specific_heat_avg": 0.259,
        "specific_heat_max": 0.42,
        "specific_heat_min": 0.13,
        "specific_heat_max_by_min": 3.2307692307692304,
        "specific_heat_first_element": 0.13,
        "specific_heat_last_element": 0.42,
        "cohesive_energy_avg_weighted_norm": 4.08125,
        "cohesive_energy_avg": 5.233333333333333,
        "cohesive_energy_max": 8.17,
        "cohesive_energy_min": 3.14,
        "cohesive_energy_max_by_min": 2.6019108280254777,
        "cohesive_energy_first_element": 8.17,
        "cohesive_energy_last_element": 4.39,
        "bulk_modulus_avg_weighted_norm": 128.5,
        "bulk_modulus_avg": 204.4,
        "bulk_modulus_max": 373.0,
        "bulk_modulus_min": 58.2,
        "bulk_modulus_max_by_min": 6.4089347079037795,
        "bulk_modulus_first_element": 373.0,
        "bulk_modulus_last_element": 182.0,
    }

    diff = DeepDiff(expected_features, actual_features, significant_digits=3)
    assert diff == {}


def test_generate_features_binary(oliynyk_db):
    formula = "NdSi2"
    actual_features = generate_features(formula, oliynyk_db)
    expected_features = {
        "formula": "NdSi2",
        "index_norm_first_element": 0.333333,
        "index_norm_last_element": 0.666667,
        "index_norm_max": 0.666667,
        "index_norm_min": 0.333333,
        "num_element": 2,
        "atomic_weight_avg_weighted_norm": 66.8042946145,
        "atomic_weight_avg": 86.16375,
        "atomic_weight_max": 144.242,
        "atomic_weight_min": 28.0855,
        "atomic_weight_max_by_min": 5.135817414680173,
        "atomic_weight_first_element": 144.242,
        "atomic_weight_last_element": 28.0855,
        "atomic_number_avg_weighted_norm": 29.333318,
        "atomic_number_avg": 37.0,
        "atomic_number_max": 60,
        "atomic_number_min": 14,
        "atomic_number_max_by_min": 4.285714285714286,
        "atomic_number_first_element": 60,
        "atomic_number_last_element": 14,
        "period_avg_weighted_norm": 3.999999,
        "period_avg": 4.5,
        "period_max": 6,
        "period_min": 3,
        "period_max_by_min": 2.0,
        "period_first_element": 6,
        "period_last_element": 3,
        "group_avg_weighted_norm": 10.333337,
        "group_avg": 8.5,
        "group_max": 14,
        "group_min": 3,
        "group_max_by_min": 4.666666666666667,
        "group_first_element": 3,
        "group_last_element": 14,
        "Mendeleev_number_avg_weighted_norm": 58.333352999999995,
        "Mendeleev_number_avg": 48.5,
        "Mendeleev_number_max": 78,
        "Mendeleev_number_min": 19,
        "Mendeleev_number_max_by_min": 4.105263157894737,
        "Mendeleev_number_first_element": 19,
        "Mendeleev_number_last_element": 78,
        "valencee_total_avg_weighted_norm": 4.666666,
        "valencee_total_avg": 5.0,
        "valencee_total_max": 6,
        "valencee_total_min": 4,
        "valencee_total_max_by_min": 1.5,
        "valencee_total_first_element": 6,
        "valencee_total_last_element": 4,
        "unpaired_electrons_avg_weighted_norm": 2.666666,
        "unpaired_electrons_avg": 3.0,
        "unpaired_electrons_max": 4,
        "unpaired_electrons_min": 2,
        "unpaired_electrons_max_by_min": 2.0,
        "unpaired_electrons_first_element": 4,
        "unpaired_electrons_last_element": 2,
        "Gilman_avg_weighted_norm": 3.666667,
        "Gilman_avg": 3.5,
        "Gilman_max": 4,
        "Gilman_min": 3,
        "Gilman_max_by_min": 1.3333333333333333,
        "Gilman_first_element": 3,
        "Gilman_last_element": 4,
        "Z_eff_avg_weighted_norm": 2.8213328330000005,
        "Z_eff_avg": 3.0715000000000003,
        "Z_eff_max": 3.822,
        "Z_eff_min": 2.321,
        "Z_eff_max_by_min": 1.6467040068935803,
        "Z_eff_first_element": 3.822,
        "Z_eff_last_element": 2.321,
        "ionization_energy_avg_weighted_norm": 7.2761342089,
        "ionization_energy_avg": 6.83835,
        "ionization_energy_max": 8.1517,
        "ionization_energy_min": 5.525,
        "ionization_energy_max_by_min": 1.475420814479638,
        "ionization_energy_first_element": 5.525,
        "ionization_energy_last_element": 8.1517,
        "coordination_number_avg_weighted_norm": 6.666664,
        "coordination_number_avg": 8.0,
        "coordination_number_max": 12,
        "coordination_number_min": 4,
        "coordination_number_max_by_min": 3.0,
        "coordination_number_first_element": 12,
        "coordination_number_last_element": 4,
        "ratio_closest_avg_weighted_norm": 0.8333335,
        "ratio_closest_avg": 0.75,
        "ratio_closest_max": 1.0,
        "ratio_closest_min": 0.5,
        "ratio_closest_max_by_min": 2.0,
        "ratio_closest_first_element": 0.5,
        "ratio_closest_last_element": 1.0,
        "polyhedron_distortion_avg_weighted_norm": 0.9973333360000001,
        "polyhedron_distortion_avg": 0.996,
        "polyhedron_distortion_max": 1.0,
        "polyhedron_distortion_min": 0.992,
        "polyhedron_distortion_max_by_min": 1.0080645161290323,
        "polyhedron_distortion_first_element": 0.992,
        "polyhedron_distortion_last_element": 1.0,
        "CIF_radius_avg_weighted_norm": 1.388333121,
        "CIF_radius_avg": 1.4945,
        "CIF_radius_max": 1.813,
        "CIF_radius_min": 1.176,
        "CIF_radius_max_by_min": 1.5416666666666667,
        "CIF_radius_first_element": 1.813,
        "CIF_radius_last_element": 1.176,
        "Pauling_radius_CN12_avg_weighted_norm": 1.483333166,
        "Pauling_radius_CN12_avg": 1.5670000000000002,
        "Pauling_radius_CN12_max": 1.818,
        "Pauling_radius_CN12_min": 1.316,
        "Pauling_radius_CN12_max_by_min": 1.3814589665653496,
        "Pauling_radius_CN12_first_element": 1.818,
        "Pauling_radius_CN12_last_element": 1.316,
        "Pauling_EN_avg_weighted_norm": 1.64666692,
        "Pauling_EN_avg": 1.52,
        "Pauling_EN_max": 1.9,
        "Pauling_EN_min": 1.14,
        "Pauling_EN_max_by_min": 1.6666666666666667,
        "Pauling_EN_first_element": 1.14,
        "Pauling_EN_last_element": 1.9,
        "Martynov_Batsanov_EN_avg_weighted_norm": 1.72000026,
        "Martynov_Batsanov_EN_avg": 1.5899999999999999,
        "Martynov_Batsanov_EN_max": 1.98,
        "Martynov_Batsanov_EN_min": 1.2,
        "Martynov_Batsanov_EN_max_by_min": 1.6500000000000001,
        "Martynov_Batsanov_EN_first_element": 1.2,
        "Martynov_Batsanov_EN_last_element": 1.98,
        "melting_point_K_avg_weighted_norm": 1551.816798,
        "melting_point_K_avg": 1486.15,
        "melting_point_K_max": 1683.15,
        "melting_point_K_min": 1289.15,
        "melting_point_K_max_by_min": 1.3056277392080053,
        "melting_point_K_first_element": 1289.15,
        "melting_point_K_last_element": 1683.15,
        "density_avg_weighted_norm": 3.88666511,
        "density_avg": 4.665,
        "density_max": 7.0,
        "density_min": 2.33,
        "density_max_by_min": 3.004291845493562,
        "density_first_element": 7.0,
        "density_last_element": 2.33,
        "specific_heat_avg_weighted_norm": 0.53666684,
        "specific_heat_avg": 0.44999999999999996,
        "specific_heat_max": 0.71,
        "specific_heat_min": 0.19,
        "specific_heat_max_by_min": 3.7368421052631575,
        "specific_heat_first_element": 0.19,
        "specific_heat_last_element": 0.71,
        "cohesive_energy_avg_weighted_norm": 4.22000041,
        "cohesive_energy_avg": 4.015,
        "cohesive_energy_max": 4.63,
        "cohesive_energy_min": 3.4,
        "cohesive_energy_max_by_min": 1.361764705882353,
        "cohesive_energy_first_element": 3.4,
        "cohesive_energy_last_element": 4.63,
        "bulk_modulus_avg_weighted_norm": 75.9333554,
        "bulk_modulus_avg": 64.9,
        "bulk_modulus_max": 98.0,
        "bulk_modulus_min": 31.8,
        "bulk_modulus_max_by_min": 3.081761006289308,
        "bulk_modulus_first_element": 31.8,
        "bulk_modulus_last_element": 98.0,
    }

    diff = DeepDiff(expected_features, actual_features, significant_digits=3)
    assert diff == {}
