// Copyright (C) 2025 EDF
// All Rights Reserved
// This code is published under the GNU Lesser General Public License (GNU LGPL)

/** \file ContinuationCutsGridAdaptNonConcave
 *  \brief Wrapper for Continuation cut object with grid adaptation for python binding
 */

#pragma once
#include <Eigen/Dense>
#include <memory>
#include <vector>
#include "StOpt/regression/BaseRegression.h"
#include "StOpt/core/grids/GridAdaptBase.h"
#include "StOpt/regression/ContinuationCutsGridAdaptNonConcave.h"


namespace StOpt
{

class ContinuationCutsGridAdaptNonConcaveWrap : public StOpt::ContinuationCutsGridAdaptNonConcave
{
public:
  ContinuationCutsGridAdaptNonConcaveWrap(  const  ContinuationCutsGridAdaptNonConcave &  p_contCut):  ContinuationCutsGridAdaptNonConcave(p_contCut) {}
  ContinuationCutsGridAdaptNonConcaveWrap(  const  std::shared_ptr< StOpt::GridAdaptBase >   &  p_grid, const  std::shared_ptr< StOpt::BaseRegression >   & p_reg , const  Eigen::ArrayXXd &  p_val):  ContinuationCutsGridAdaptNonConcave(   p_grid,  p_reg ,  p_val) {}
  ContinuationCutsGridAdaptNonConcaveWrap( const  std::shared_ptr< StOpt::BaseRegression >   & p_reg ):  ContinuationCutsGridAdaptNonConcave(  p_reg) {}


  std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, Eigen::ArrayXXd  > >  getCutsASimByCoord(const  Eigen::ArrayXXd &  p_hypStock, const Eigen::ArrayXd &p_coordinates) const
  {
    std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, std::shared_ptr<Eigen::ArrayXXd> >  >   retA = StOpt::ContinuationCutsGridAdaptNonConcave::getCutsASim( p_hypStock, p_coordinates);
    std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, Eigen::ArrayXXd  > > ret(retA.size());
    for (size_t i=0; i < ret.size(); ++i)
      {
	ret[i]= std::make_pair(retA[i].first, *retA[i].second);
      }
    return ret;
  }
   std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, Eigen::ArrayXXd  > >  getCutsASimByNumber(const  Eigen::ArrayXXd &  p_hypStock, const int  & p_isim) const
  {
    std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, std::shared_ptr<Eigen::ArrayXXd> >  >   retA = StOpt::ContinuationCutsGridAdaptNonConcave::getCutsASim( p_hypStock, p_isim);
   std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, Eigen::ArrayXXd  > > ret(retA.size());
    for (size_t i=0; i < ret.size(); ++i)
      {
	ret[i]= std::make_pair(retA[i].first, *retA[i].second);
      }
    return ret;  
  }
  std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, Eigen::ArrayXXd > >  getCutsConcGatherASimByCoord(const  Eigen::ArrayXXd &  p_hypStock, const Eigen::ArrayXd &p_coordinates, const bool &  p_bStrictConc) const
  {
    std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, std::shared_ptr<Eigen::ArrayXXd> >  >   retA = StOpt::ContinuationCutsGridAdaptNonConcave::getCutsConcGatherASim( p_hypStock, p_coordinates,p_bStrictConc);
   std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, Eigen::ArrayXXd  > > ret(retA.size());
    for (size_t i=0; i < ret.size(); ++i)
      {
	ret[i]= std::make_pair(retA[i].first, *retA[i].second);
      }
    return ret; 
  }
    std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, Eigen::ArrayXXd > >  getCutsConcGatherASimByNumber(const  Eigen::ArrayXXd &  p_hypStock, const int & p_isim, const bool &  p_bStrictConc) const
  {
    std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, std::shared_ptr<Eigen::ArrayXXd> >  >   retA = StOpt::ContinuationCutsGridAdaptNonConcave::getCutsConcGatherASim( p_hypStock, p_isim,p_bStrictConc);
   std::vector< std::pair <std::shared_ptr< StOpt::GridAdaptBase>, Eigen::ArrayXXd  > > ret(retA.size());
    for (size_t i=0; i < ret.size(); ++i)
      {
	ret[i]= std::make_pair(retA[i].first, *retA[i].second);
      }
    return ret; 
  } 
};
  
}
