"""
This module contains a test noisy function
"""

import numpy as np
from numpy.linalg import norm
from numpy import cos, sin


def func_wrapper(H, persis_info, sim_specs, libE_info):
    """
    Wraps an objective function

    .. seealso::
        `test_persistent_fd_param_finder.py` <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_persistent_fd_param_finder.py>`_ # noqa
    """

    batch = len(H["x"])
    H0 = np.zeros(batch, dtype=sim_specs["out"])

    for i, x in enumerate(H["x"]):
        H0["f_val"][i] = noisy_function(x)[H["f_ind"][i]]

    return H0, persis_info


def noisy_function(x):
    """ """

    x1 = x[0]
    x2 = x[1]
    term1 = (4 - 2.1 * x1**2 + (x1**4) / 3) * x1**2
    term2 = x1 * x2
    term3 = (-4 + 4 * x2**2) * x2**2

    phi1 = 0.9 * sin(100 * norm(x, 1)) * cos(100 * norm(x, np.inf)) + 0.1 * cos(norm(x, 2))
    phi1 = phi1 * (4 * phi1**2 - 3)

    phi2 = 0.8 * sin(100 * norm(x, 1)) * cos(100 * norm(x, np.inf)) + 0.2 * cos(norm(x, 2))
    phi2 = phi2 * (4 * phi2**2 - 3)

    phi3 = 0.7 * sin(100 * norm(x, 1)) * cos(100 * norm(x, np.inf)) + 0.3 * cos(norm(x, 2))
    phi3 = phi3 * (4 * phi3**2 - 3)

    F = np.zeros(3)
    F[0] = (1 + 1e-1 * phi1) * term1
    F[1] = (1 + 1e-2 * phi2) * term2
    F[2] = (1 + 1e-3 * phi3) * term3

    return F
