/*****************************************************************//**
 * \file   CutGeneratorAbstractAbstract.h
  * \brief lass representing the second important part of the Chain of Responsibility design pattern (the base handler) that organizes the chain dealing with the choice of the pricing algorithm used when solving the pricing subproblem in column generation.
 *
 * \author talmefta
 * \date   October 2022
 *********************************************************************/
#ifndef CutGeneratorAbstract_H
#define CutGeneratorAbstract_H

#include "CutGenerator.h"

 /**
  * \class CutGeneratorAbstractAbstract
  * \brief class representing the second important part of the Chain of Responsibility design pattern (the base handler) that organizes the chain dealing with the choice of the pricing algorithm used when solving the pricing subproblem in column generation.
  */


template<class RestrictedMasterProblem, class PricingSubProblem, class ColumnGeneration, class ConstraintType>
class CutGeneratorAbstract : public CutGenerator<RestrictedMasterProblem, PricingSubProblem, ColumnGeneration, ConstraintType> {

protected:
    CutGenerator<RestrictedMasterProblem, PricingSubProblem, ColumnGeneration, ConstraintType>* next_cutter; /**< The next algorithm in the chain of responsibility..*/
    vector<CutFamilyInformation*> information;
public:
    /**
     * \brief Constructor.
     *
     */
    CutGeneratorAbstract() : next_cutter(nullptr), information() {}

    CutGenerator<RestrictedMasterProblem, PricingSubProblem, ColumnGeneration, ConstraintType>* get_next_cutter() override {
        return this->next_cutter;
    }

    vector<CutFamilyInformation*>& get_information() override {
        return this->information;
    }


    /**
    * \brief Sets the next algorithm operator in the chain of responsibility in the base handler class (here, the CutGeneratorAbstractAbstract).
    * \param _next_algorithm : CutGeneratorAbstract<PricingSubProblem>*
    * \return _next_algorithm to let us link the algorithms operators in a convenient way (algorithm1->set_next_algorithm(handler2)->set_next_algorithm(handler3)) : CutGeneratorAbstract<Instance, ColumnsType, DualVariables>*.
    */
    CutGenerator<RestrictedMasterProblem, PricingSubProblem, ColumnGeneration, ConstraintType>* set_next_cutter(CutGenerator<RestrictedMasterProblem, PricingSubProblem, ColumnGeneration, ConstraintType>* _next_cutter) override {
        this->next_cutter = _next_cutter;
        return this->next_cutter;
    }

    /**
     * \brief Evaluates if the handler (the algorithm) can handle (solve) the cutting procedure based on the code of request.
     *
     * \param request : string
     * \return True if the concrete algorithm can find the cuts, false otherwise.
     */
    virtual bool can_cut(const string& request) const = 0;

    /**
     * Solves the pricing sub-problem and stores the solution in solution.
     * \details This method has to be implemented in the inherent classes.
     * \param request : string
     */
    virtual bool cut(Node<RestrictedMasterProblem, PricingSubProblem, ColumnGeneration, ConstraintType>& node) override {
        if (this->next_cutter)
            return this->next_cutter->cut(node);
        return false;
    }
};

#endif //CutGeneratorAbstractABSTRACT_H

