/*****************************************************************//**
 * \file   PricingSubProblemAlgorithm.h
 * \brief  Reperesents the interface of pricing subproblem algorithm with a virtual pure algorithm to override by inherent classes depending on the choosed algorithm to solve the pricing subproblem.
 *
 * \author talmefta
 * \date   May 2022
 *********************************************************************/
#ifndef PRICINGSUBPROBLEMALGORITHM_H
#define PRICINGSUBPROBLEMALGORITHM_H

#include "Header.h"
#include "Constraint.h"
 /**
  * \class PricingSubProblemAlgorithm
  * \brief Interface of Chain of responsability design pattern dealing with the choice of the pricing algorithm used when ssolving the pricing subproblem in column generation.
  */

template<class Instance, class ColumnsType, class DualVariables, class ConstraintType> 
class PricingSubProblemAlgorithm {

protected:
    bool           fails_to_find_favorably_priced_columns = true; /**< A boolean flag to store if the algorithm does not find any favorably priced columns.*/
    string                                                   name;
    double                                                   value;
    bool is_early_terminated;
    int	favourablyPricedVariablesCounter;
    bool is_exact_pricing_required;
    clock_t	start_time;

public:
    /**
     * Virtual destructor.
     *
     */
    virtual ~PricingSubProblemAlgorithm() {}

     /**
     * \brief Sets the next algorithm operator in the chain of responsibility in the base handler class (here, the PricingSubProblemAlgorithmAbstract).
     * \param _next_algorithm : PricingSubProblemAlgorithm< PricingSubProblem>*
     * \return _next_algorithm to let us link the algorithms operators in a convenient way (algorithm1->set_next_algorithm(handler2)->set_next_algorithm(handler3)) : PricingSubProblemAlgorithm<Instance, ColumnsType, DualVariables>*.
     */
    virtual PricingSubProblemAlgorithm<Instance, ColumnsType, DualVariables, ConstraintType>* set_next_algorithm(PricingSubProblemAlgorithm<Instance, ColumnsType, DualVariables, ConstraintType>* _next_algorithm) = 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 ColumnsType solve(const string& request, const double time_limit) = 0;

    virtual PricingSubProblemAlgorithm<Instance, ColumnsType, DualVariables, ConstraintType>* get_next_algorithm() = 0;

    //virtual void buildDualPrices();

    /**
     * Returns if the algorithm fails to find negtaive (positive) columns after solving the pricing subproblem.
     *
     * \return fails_to_find_favorably_priced_columns: bool
     */
    bool has_failed_to_find_favorably_priced_columns() const {
        return this->fails_to_find_favorably_priced_columns;
    }

    const string& get_name() const {
        return this->name;
    }

    const double& get_value() const {
        return this->value;
    }

    const bool& get_is_early_terminated() const {
        return this->is_early_terminated;
    }

    const bool& get_is_exact_pricing_required() const {
        return this->is_exact_pricing_required;
    }

    void set_name(const string& new_value) {
        this->name = new_value;
    }

    void set_start_time(const clock_t& start) {
        this->start_time = start;
    }

};

#endif //PRICINGSUBPROBLEMALGORITHM_H