#include "array.hpp"

void array_reg_helper<array<std::string>, std::string, false>::reg(interpreter_context& context) {
    context.register_commutative_operator<array_t, array_t>("+", [&context](const symbol& s1, const symbol& s2) {
        const array_t& a1 = s1.as<array_t>();
        const array_t& a2 = s2.as<array_t>();
        if (a1.size() != a2.size()) {
            context.error("operator 'array + array' requires arrays of equal lengths");
            throw parser_exception();
        }
        array_t* na = new array_t(a1.size());
        for (std::size_t i = 0; i < a1.size(); ++i) {
            (*na)[i] = a1[i] + a2[i];
        }
        return na;
    });

    context.register_function<array_t>("trim", [&context](const std::vector<symbol>& args) {
        const array_t& a = args[0].as<array_t>();
        array_t* na = new array_t(a);
        for (auto& s : *na) {
            s = trim(s);
        }

        return na;
    });

    context.register_function<array_t, string>("trim", [&context](const std::vector<symbol>& args) {
        const array_t&     a     = args[0].as<array_t>();
        const std::string& chars = args[1].as<string>().value;
        array_t* na = new array_t(a);
        for (auto& s : *na) {
            s = trim(s, chars);
        }

        return na;
    });

    context.register_function<string, string, string>("replace", [&context](const std::vector<symbol>& args) {
        const array_t&     a     = args[0].as<array_t>();
        const std::string& token = args[1].as<string>().value;
        const std::string& rep   = args[2].as<string>().value;
        array_t* na = new array_t(a);
        for (auto& s : *na) {
            std::size_t pos = s.find(token);
            while (pos != s.npos) {
                s.replace(pos, token.size(), rep);
                pos = s.find(token, pos + rep.size());
            }
        }

        return na;
    });
}
