#include <language/modules/CompositeSchemeOtherFluxesModule.hpp>

#include <language/modules/MeshModuleTypes.hpp>
#include <language/modules/SchemeModuleTypes.hpp>
#include <language/utils/BuiltinFunctionEmbedder.hpp>
#include <language/utils/TypeDescriptor.hpp>
#include <scheme/DiscreteFunctionVariant.hpp>
#include <scheme/IBoundaryConditionDescriptor.hpp>

#include <language/modules/ModuleRepository.hpp>

#include <scheme/AcousticCompositeSolver.hpp>
#include <scheme/RoeViscousFormEulerianCompositeSolver_v2.hpp>
#include <scheme/RoeViscousFormEulerianCompositeSolver_v2_o2.hpp>
#include <scheme/RusanovEulerianCompositeSolver.hpp>
#include <scheme/RusanovEulerianCompositeSolver_o2.hpp>
#include <scheme/RusanovEulerianCompositeSolver_v2.hpp>
#include <scheme/RusanovEulerianCompositeSolver_v2_o2.hpp>
#include <scheme/RusanovEulerianCompositeSolver_v2_order_n.hpp>
#include <scheme/HybridRoeRusanovViscousFormEulerianCompositeSolver_v2.hpp>
#include <scheme/HybridRusanovRoeViscousFormEulerianCompositeSolver_v2.hpp>
#include <scheme/HybridHLLRusanovEulerianCompositeSolver_v2.hpp>
#include <scheme/HybridHLLcRusanovEulerianCompositeSolver_v2.hpp>


CompositeSchemeOtherFluxesModule::CompositeSchemeOtherFluxesModule() {

    this->_addBuiltinFunction("hybrid_roe_rusanov_eulerian_composite_solver_version2",
        std::function(
    
          [](const std::shared_ptr<const DiscreteFunctionVariant>& rho,
             const std::shared_ptr<const DiscreteFunctionVariant>& u,
             const std::shared_ptr<const DiscreteFunctionVariant>& E, const double& gamma,
             const std::shared_ptr<const DiscreteFunctionVariant>& c,
             const std::shared_ptr<const DiscreteFunctionVariant>& p,   // const size_t& degree,
             const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&
               bc_descriptor_list,
             const double& dt) -> std::tuple<std::shared_ptr<const DiscreteFunctionVariant>,
                                             std::shared_ptr<const DiscreteFunctionVariant>,
                                             std::shared_ptr<const DiscreteFunctionVariant>> {
            return hybridRoeRusanovViscousFormEulerianCompositeSolver_v2(rho, u, E, gamma, c, p,   // degree,
                                                  bc_descriptor_list, dt);
          }
    
          )); 

    this->_addBuiltinFunction("hybrid_rusanov_roe_eulerian_composite_solver_version2",
        std::function(
    
          [](const std::shared_ptr<const DiscreteFunctionVariant>& rho,
             const std::shared_ptr<const DiscreteFunctionVariant>& u,
             const std::shared_ptr<const DiscreteFunctionVariant>& E, const double& gamma,
             const std::shared_ptr<const DiscreteFunctionVariant>& c,
             const std::shared_ptr<const DiscreteFunctionVariant>& p,   // const size_t& degree,
             const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&
               bc_descriptor_list,
             const double& dt) -> std::tuple<std::shared_ptr<const DiscreteFunctionVariant>,
                                             std::shared_ptr<const DiscreteFunctionVariant>,
                                             std::shared_ptr<const DiscreteFunctionVariant>> {
            return hybridRusanovRoeViscousFormEulerianCompositeSolver_v2(rho, u, E, gamma, c, p,   // degree,
                                                  bc_descriptor_list, dt);
          }
    
          )); 

    this->_addBuiltinFunction("hybrid_hll_rusanov_eulerian_composite_solver_version2",
        std::function(
    
          [](const std::shared_ptr<const DiscreteFunctionVariant>& rho,
             const std::shared_ptr<const DiscreteFunctionVariant>& u,
             const std::shared_ptr<const DiscreteFunctionVariant>& E, const double& gamma,
             const std::shared_ptr<const DiscreteFunctionVariant>& c,
             const std::shared_ptr<const DiscreteFunctionVariant>& p,   // const size_t& degree,
             const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&
               bc_descriptor_list,
             const double& dt) -> std::tuple<std::shared_ptr<const DiscreteFunctionVariant>,
                                             std::shared_ptr<const DiscreteFunctionVariant>,
                                             std::shared_ptr<const DiscreteFunctionVariant>> {
            return hybridHLLRusanovEulerianCompositeSolver_v2(rho, u, E, gamma, c, p,   // degree,
                                                  bc_descriptor_list, dt);
          }
    
          )); 

    this->_addBuiltinFunction("hybrid_hllc_rusanov_eulerian_composite_solver_version2",
        std::function(
    
          [](const std::shared_ptr<const DiscreteFunctionVariant>& rho,
             const std::shared_ptr<const DiscreteFunctionVariant>& u,
             const std::shared_ptr<const DiscreteFunctionVariant>& E, const double& gamma,
             const std::shared_ptr<const DiscreteFunctionVariant>& c,
             const std::shared_ptr<const DiscreteFunctionVariant>& p,   // const size_t& degree,
             const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&
               bc_descriptor_list,
             const double& dt) -> std::tuple<std::shared_ptr<const DiscreteFunctionVariant>,
                                             std::shared_ptr<const DiscreteFunctionVariant>,
                                             std::shared_ptr<const DiscreteFunctionVariant>> {
            return hybridHLLcRusanovEulerianCompositeSolver_v2(rho, u, E, gamma, c, p,   // degree,
                                                  bc_descriptor_list, dt);
          }
    
          )); 
}

void
CompositeSchemeOtherFluxesModule::registerOperators() const
{}

void
CompositeSchemeOtherFluxesModule::registerCheckpointResume() const
{}

ModuleRepository::Subscribe<CompositeSchemeOtherFluxesModule> composite_scheme_other_fluxes_module;