from typing import Any

import numpy as np

import gnomes


NUM_DASHES = 40


def compare_expected_actual(expected: Any, actual: Any) -> None:
    print("-----")
    print(f"Expected: {expected}")
    print(f"  Actual: {actual}")
    if expected == actual:
        print("PASS")
    else:
        print("FAIL")


def compare_expected_actual_array(
        expected: np.ndarray, actual: np.ndarray
        ) -> None:
    print("-----")
    print(f"Expected: {expected}")
    print(f"  Actual: {actual}")
    if np.array_equal(expected, actual):
        print("PASS")
    else:
        print("FAIL")


def test_gnomes_player_fit() -> None:
    print("-" * NUM_DASHES)
    print("Testing GnomesPlayer.fit()")

    X = np.array([2, 10, 7, 20])
    y = np.array([0, 1, 1, 0])

    gp = gnomes.GnomesPlayer()
    gp.fit(X, y)

    compare_expected_actual(7, gp.lowest_gnome_nook)
    compare_expected_actual(10, gp.highest_gnome_nook)

    X = np.array([2, 10, 7, 20])
    y = np.array([1, 0, 1, 0])

    gp2 = gnomes.GnomesPlayer()
    gp2.fit(X, y)

    compare_expected_actual(2, gp2.lowest_gnome_nook)
    compare_expected_actual(7, gp2.highest_gnome_nook)


def test_gnomes_player_predict_range() -> None:
    print("-" * NUM_DASHES)
    print("Testing GnomesPlayer.predict()")

    X_train = np.array([2, 10, 7, 20])
    y_train = np.array([0, 1, 1, 0])

    gp = gnomes.GnomesPlayer()
    gp.fit(X_train, y_train)

    X_test = np.array([1, 7, 9, 10, 15])
    preds = gp.predict(X_test)

    expected = np.array([0, 1, 1, 1, 0])
    compare_expected_actual_array(expected, preds)

    gp2 = gnomes.GnomesPlayer()
    X_train = np.array([2, 10, 7, 20])
    y_train = np.array([1, 0, 1, 0])

    gp2.fit(X_train, y_train)

    X_test = np.array([1, 7, 9, 10, 15])
    preds = gp2.predict(X_test)

    expected = np.array([0, 1, 0, 0, 0])
    compare_expected_actual_array(expected, preds)


def run_all_tests() -> None:
    test_gnomes_player_fit()
    test_gnomes_player_predict_range()


if __name__ == "__main__":
    run_all_tests()
