#include "base/datatypes.h"
#include "parser.h"
#include "tbpm/config.h"

#ifndef TBPLAS_PYTHON_INTERFACE_TBPM_H
#define TBPLAS_PYTHON_INTERFACE_TBPM_H

namespace tbplas::python {
using tbplas::base::complex_t;
using tbplas::tbpm::TBPMConfig;

template <typename solver_t>
void set_config(
    solver_t* solver,
    const std::string& config_name)
{
    TBPMConfig& config = solver->config;
    InputParser input(config_name);
    // Set config mode to python.
    config.python_mode = true;
    input.read_single("prefix", config.prefix);
    input.read_single("save_data", config.save_data);
    input.read_single("dimension", config.dimension);
    input.read_single("temperature", config.temperature);
    input.read_single("mu", config.mu);
    input.read_single("num_spin", config.num_spin);
    input.read_single("algo", config.algo);
    input.read_single("pool_size", config.pool_size);
    input.read_single("rescale", config.rescale);
    input.read_single("bessel_precision", config.bessel_precision);
    input.read_single("num_random_samples", config.num_random_samples);
    input.read_single("num_time_steps", config.num_time_steps);
    input.read_single("seed", config.seed);
    input.read_single("wfn_check_time_steps", config.wfn_check_time_steps);
    input.read_single("wfn_check_threshold", config.wfn_check_threshold);
    input.read_single("fermi_cheb_precision", config.fermi_cheb_precision);
    input.read_single("num_fermi_fft_steps", config.num_fermi_fft_steps);
    input.read_single("ldos", config.ldos);
    input.read_set("ldos_orbital_indices", config.ldos_orbital_indices);
    input.read_single("ldos_delta", config.ldos_delta);
    input.read_single("ldos_recursion_depth", config.ldos_recursion_depth);
    input.read_eigen("k_points", config.k_points, true);
    input.read_single("dyn_pol_back_epsilon", config.dyn_pol_back_epsilon);
    input.read_single("dyn_pol_coulomb_factor", config.dyn_pol_coulomb_factor);
    input.read_eigen("dyn_pol_q_points", config.dyn_pol_q_points, true);
    input.read_vector_tuple("dc_cond_energy_limits", config.dc_cond_energy_limits);
    input.read_single("dc_cond_num_time_steps", config.dc_cond_num_time_steps);
    input.read_eigen("dckb_energies", config.dckb_energies, false);
    input.read_single("dckb_num_kernel", config.dckb_num_kernel);
    input.read_single("dckb_num_integ_steps", config.dckb_num_integ_steps);
    input.read_single("dckb_component", config.dckb_component);
    input.read_single("dckb_unit", config.dckb_unit);
    input.read_eigen("qe_energies", config.qe_energies, false);
    input.read_set("wft_time_save", config.wft_time_save);
    input.read_single("wft_dt_scale", config.wft_dt_scale);
}

template <typename solver_t>
void set_wf0(
    solver_t* solver,
    const complex_t* wf0,
    size_t num_orb)
{
    solver->config.set_wft_wf0(wf0, num_orb);
}

template <typename solver_t>
void unset_wf0(solver_t* solver)
{
    solver->config.set_wft_wf0(nullptr, 0);
}
} // namespace tbplas::python

#endif