/*****************************************************************//**
 * \file   BranchingRuleAbstract.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 BranchingRuleAbstract_H
#define BranchingRuleAbstract_H

#include "BranchingRule.h"

 /**
  * \class BranchingRuleAbstractAbstract
  * \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 BranchingRuleAbstract : public BranchingRule<RestrictedMasterProblem, PricingSubProblem, ColumnGeneration, ConstraintType> {

protected:
    BranchingRule<RestrictedMasterProblem, PricingSubProblem, ColumnGeneration, ConstraintType>* next_branching_rule; /**< The next algorithm in the chain of responsibility..*/

public:
    /**
     * \brief Constructor.
     *
     */
    BranchingRuleAbstract() : next_branching_rule(nullptr) {}

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

    /**
     * \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_branch(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
     */
    list<Node<RestrictedMasterProblem, PricingSubProblem,
        ColumnGeneration, GRBConstr>> branch(Node<RestrictedMasterProblem, PricingSubProblem, ColumnGeneration, GRBConstr>& node) const override {
        if (this->next_branching_rule)
            return this->next_branching_rule->branch(node);
        return list<Node<RestrictedMasterProblem, PricingSubProblem,
            ColumnGeneration, GRBConstr>>();
    }
};

#endif //BranchingRuleAbstractABSTRACT_H

