// Copyright (c) 2019, QuantStack and Mamba Contributors
//
// Distributed under the terms of the BSD 3-Clause License.
//
// The full license is in the file LICENSE, distributed with this software.
#ifndef MAMBA_CORE_SOLVER_HPP
#define MAMBA_CORE_SOLVER_HPP
#include <iosfwd>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include <solv/pooltypes.h>
#include <solv/solvable.h>
// Incomplete header
#include <solv/rules.h>
#include "mamba/core/package_info.hpp"
#include "mamba/core/pool.hpp"
#include "match_spec.hpp"
#define MAMBA_NO_DEPS 0b0001
#define MAMBA_ONLY_DEPS 0b0010
#define MAMBA_FORCE_REINSTALL 0b0100
extern "C"
{
typedef struct s_Solver Solver;
}
namespace mamba::solv
{
class ObjQueue;
}
namespace mamba
{
const char* solver_ruleinfo_name(SolverRuleinfo rule);
struct MSolverProblem
{
SolverRuleinfo type;
Id source_id;
Id target_id;
Id dep_id;
std::optional<PackageInfo> source;
std::optional<PackageInfo> target;
std::optional<std::string> dep;
std::string description;
};
class MSolver
{
public:
MSolver(MPool pool, std::vector<std::pair<int, int>> flags = {});
~MSolver();
MSolver(const MSolver&) = delete;
MSolver& operator=(const MSolver&) = delete;
MSolver(MSolver&&) = delete;
MSolver& operator=(MSolver&&) = delete;
void add_global_job(int job_flag);
void add_jobs(const std::vector<std::string>& jobs, int job_flag);
void add_constraint(const std::string& job);
void add_pin(const std::string& pin);
void add_pins(const std::vector<std::string>& pins);
void set_flags(const std::vector<std::pair<int, int>>& flags);
void set_postsolve_flags(const std::vector<std::pair<int, int>>& flags);
[[nodiscard]] bool try_solve();
void must_solve();
[[nodiscard]] bool is_solved() const;
[[nodiscard]] std::string problems_to_str() const;
[[nodiscard]] std::vector<std::string> all_problems() const;
[[nodiscard]] std::vector<MSolverProblem> all_problems_structured() const;
[[nodiscard]] std::string all_problems_to_str() const;
std::ostream& explain_problems(std::ostream& out) const;
[[nodiscard]] std::string explain_problems() const;
[[nodiscard]] const MPool& pool() const&;
[[nodiscard]] MPool& pool() &;
[[nodiscard]] MPool&& pool() &&;
[[nodiscard]] const std::vector<MatchSpec>& install_specs() const;
[[nodiscard]] const std::vector<MatchSpec>& remove_specs() const;
[[nodiscard]] const std::vector<MatchSpec>& neuter_specs() const;
[[nodiscard]] const std::vector<MatchSpec>& pinned_specs() const;
operator const Solver*() const;
operator Solver*();
bool only_deps = false;
bool no_deps = false;
bool force_reinstall = false;
private:
void add_channel_specific_job(const MatchSpec& ms, int job_flag);
void add_reinstall_job(MatchSpec& ms, int job_flag);
std::vector<std::pair<int, int>> m_flags;
std::vector<MatchSpec> m_install_specs;
std::vector<MatchSpec> m_remove_specs;
std::vector<MatchSpec> m_neuter_specs;
std::vector<MatchSpec> m_pinned_specs;
bool m_is_solved;
// Order of m_pool and m_solver is critical since m_pool must outlive m_solver.
MPool m_pool;
std::unique_ptr<::Solver, void (*)(::Solver*)> m_solver;
std::unique_ptr<solv::ObjQueue> m_jobs;
};
} // namespace mamba
#endif // MAMBA_SOLVER_HPP