"""
@Author: Created by Caleb Ju at Argonne National Labs as Given's associate,
         Summer 2021.
"""
import numpy as np
import scipy.optimize as sciopt

from libensemble.message_numbers import STOP_TAG, PERSIS_STOP, FINISHED_PERSISTENT_GEN_TAG
from libensemble.tools.consensus_subroutines import print_final_score, get_grad, get_func


def independent_optimize(H, persis_info, gen_specs, libE_info):
    """Uses scipy.optimize to solve objective function"""
    ub = gen_specs["user"]["ub"]
    lb = gen_specs["user"]["lb"]

    eps = persis_info["params"]["eps"]
    f_i_idxs = persis_info["f_i_idxs"]

    def _f(x):
        tag, f_val = get_func(x, f_i_idxs, gen_specs, libE_info)
        if tag in [STOP_TAG, PERSIS_STOP]:
            return np.inf
        return f_val

    def _df(x):
        tag, gradf_val = get_grad(x, f_i_idxs, gen_specs, libE_info)
        if tag in [STOP_TAG, PERSIS_STOP]:
            # Trick optimizer to think we found minimum
            return np.zeros(len(x))
        return gradf_val

    while 1:
        x0 = persis_info["rand_stream"].uniform(low=lb, high=ub)

        res = sciopt.minimize(
            _f,
            x0,
            jac=_df,
            method="BFGS",
            tol=eps,
            options={
                "gtol": eps,
                "norm": np.inf,
                "maxiter": None,
            },
        )
        print_final_score(res.x, f_i_idxs, gen_specs, libE_info)

        start_pt, end_pt = f_i_idxs[0], f_i_idxs[-1]
        print("[Worker {}]: x={}".format(persis_info["worker_num"], res.x[2 * start_pt : 2 * end_pt]), flush=True)
        """
        try:
           res = sciopt.minimize(_f, x0, jac=_df, method="BFGS", tol=eps,
                                  options={'gtol': eps, 'norm': np.inf, 'maxiter': None})
           print_final_score(res.x, f_i_idxs, gen_specs, libE_info)

        except:
           print('hi', flush=True)
           return None, persis_info, FINISHED_PERSISTENT_GEN_TAG
        """

        return None, persis_info, FINISHED_PERSISTENT_GEN_TAG
