/*****************************************************************//**
 * \file   RestrictedMasterProblemInitializerAbstract.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   May 2022
 *********************************************************************/
#ifndef RESTRICTEDMASTERPROBLEMINITIALIZERABSTRACT_H
#define RESTRICTEDMASTERPROBLEMINITIALIZERABSTRACT_H

#include "RestrictedMasterProblemInitializer.h"

 /**
  * \class RestrictedMasterProblemInitializerAbstract
  * \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.
  */

template<class Instance, class ColumnsType>
class RestrictedMasterProblemInitializerAbstract : public RestrictedMasterProblemInitializer<Instance, ColumnsType> {

protected:
    Instance&                                                           instance; /**< The studied instance.*/
    RestrictedMasterProblemInitializer<Instance, ColumnsType>*    next_algorithm; /**< The next algorithm in the chain of responsibility.*/
    double                                                                  cost;
    int exchangesPerVertex;

public:
    /**
     * \brief Constructor.
     *
     */
    RestrictedMasterProblemInitializerAbstract(Instance& instance): instance(instance), next_algorithm(NULL), cost() {}

    /**
    * \brief Sets the next algorithm operator in the chain of responsibility in the base handler class (here, the RestrictedMasterProblemInitializer).
    * \param _next_algorithm : PricingSubProblemAlgorithm< PricingSubProblem, SolutionType>*
    * \return _next_algorithm to let us link the algorithms operators in a convenient way (algorithm1->set_next_algorithm(handler2)->set_next_algorithm(handler3)) : RestrictedMasterProblemInitializer<Instance, ColumnsType>*.
    */
    RestrictedMasterProblemInitializer<Instance, ColumnsType>* set_next_algorithm(RestrictedMasterProblemInitializer<Instance, ColumnsType>* _next_algorithm) override {
        this->next_algorithm = _next_algorithm;
        return this->next_algorithm;
    }

    /**
     * \brief Evaluates if the handler (the algorithm) can handle (initlize) the restricted master problem based on the code of request.
     *
     * \param request : const string& request
     * \return True if the concrete algorithm can solve the pricing sub-problem, false otherwise.
     */
    virtual bool can_initialize(const string& request) const = 0;

    /**
     * Initializes the restrcted master problem.
     * \details This method has to be implemented in the inherent classes.
     * \param request : const string& request
     */
    virtual ColumnsType initialize(const string& request) override {
        if (this->next_algorithm)
            return this->next_algorithm->initialize(request);
        return ColumnsType();
    }

    virtual RestrictedMasterProblemInitializer<Instance, ColumnsType>* get_next_algorithm() override {
        return this->next_algorithm;
    }

    /**
    * Get method of member cost that will be in the abstract class of initlizer.
    *
    * \return cost : const double&
    */
    virtual const double& get_cost() const override {
        return this->cost;
    }
};

#endif //RESTRICTEDMASTERPROBLEMINITIALIZERABSTRACT_H