#pragma once
#include <alib/string>
#include <vector>

#include <abstraction/Value.hpp>

class Algorithm {
    friend class Registry;
public:

    struct Overload {
        Overload(ext::string p_returnType, std::vector<ext::string> p_parameterTypes);

        ext::string returnType;
        std::vector<ext::string> parameterTypes;
    };

    explicit Algorithm(std::string p_fullName);

    const std::vector<std::string>& getGroups() const { return this->groups; }

    const std::string& getFullName() const { return this->fullName; }
    std::string getPrettyName() const;

    size_t getInputCount() const;

    std::shared_ptr<abstraction::Value> execute(
            const std::vector<std::shared_ptr<abstraction::Value>>& params) const;

private:
    void addOverload(Overload overload);
    bool canAddOverload(const Overload& overload);

    std::string name;
    std::string fullName;
    std::vector<std::string> groups;
    std::vector<Overload> overloads;
};


