//
// Created by marvin on 27.11.18.
//

#include "weighted_double_evaluator.h"

#include "../evaluation_context.h"
#include "../evaluation_result.h"
#include "../option_parser.h"
#include "../plugin.h"

#include <cstdlib>
#include <sstream>

using namespace std;

namespace weighted_double_evaluator {
    WeightedDoubleEvaluator::WeightedDoubleEvaluator(const Options &opts)
            : evaluator(opts.get<shared_ptr<Evaluator>>("eval")),
              w(opts.get<double>("weight")) {
    }

    WeightedDoubleEvaluator::WeightedDoubleEvaluator(const shared_ptr<Evaluator> &eval, double weight)
            : evaluator(eval), w(weight) {
    }

    WeightedDoubleEvaluator::~WeightedDoubleEvaluator() {
    }

    bool WeightedDoubleEvaluator::dead_ends_are_reliable() const {
        return evaluator->dead_ends_are_reliable();
    }

    EvaluationResult WeightedDoubleEvaluator::compute_result(
            EvaluationContext &eval_context) {
        // Note that this produces no preferred operators.
        EvaluationResult result;
        int value = eval_context.get_evaluator_value_or_infinity(evaluator.get());
        if (value != EvaluationResult::INFTY) {
            // TODO: Check for overflow?
            value *= w;
        }
        result.set_evaluator_value(value);
        return result;
    }

    void WeightedDoubleEvaluator::get_path_dependent_evaluators(set<Evaluator *> &evals) {
        evaluator->get_path_dependent_evaluators(evals);
    }

    static shared_ptr<Evaluator> _parse(OptionParser &parser) {
        parser.document_synopsis(
                "Weighted evaluator",
                "Multiplies the value of the evaluator with the given weight.");
        parser.add_option<shared_ptr<Evaluator>>("eval", "evaluator");
        parser.add_option<int>("weight", "weight");
        Options opts = parser.parse();
        if (parser.dry_run())
            return nullptr;
        else
            return make_shared<WeightedDoubleEvaluator>(opts);
    }

    static Plugin<Evaluator> _plugin("weight_double", _parse, "evaluators_basic");
}
