#pragma once

#include "CoreConcept.h"

using namespace ddb;

class SwordfishFunctionDef : public FunctionDef {
public:
    SwordfishFunctionDef(const std::function<ConstantSP(ddb::vector<ConstantSP>&)> func, const std::string &name, int minParamNum, int maxParamNum, bool hasReturnValue)
        : FunctionDef(FUNCTIONDEF_TYPE::USERDEFFUNC, name, minParamNum, maxParamNum, hasReturnValue),
          func_(func), minParamNum_(minParamNum), maxParamNum_(maxParamNum), hasReturnValue_(hasReturnValue) {
    }
    ~SwordfishFunctionDef() {
        func_ = nullptr;
    }
    IO_ERR serialize(Heap* pHeap, const ByteArrayCodeBufferSP& buffer) const {
        throw RuntimeException("unsupport serialize SwordfishFunctionDef.");
    }
    ConstantSP getInstance() const {
        throw RuntimeException("unsupport getInstance of SwordfishFunctionDef.");
    }
    ConstantSP getValue() const {
        return new SwordfishFunctionDef(func_, name_, minParamNum_, maxParamNum_, hasReturnValue_);
    }
    ConstantSP call(Heap* pHeap, vector<ConstantSP>& arguments) {
        return func_(arguments);
    }
    ConstantSP call(Heap* pHeap, const ConstantSP& a, const ConstantSP& b) {
        std::vector<ConstantSP> args;
        args.push_back(a);
        args.push_back(b);
        return call(pHeap, args);
    }
    ConstantSP call(Heap* pHeap,vector<ObjectSP>& arguments) {
        std::vector<ConstantSP> args;
        args.reserve(arguments.size());
        for (const auto &arg : arguments) {
            args.push_back(arg->getValue(pHeap));
        }
        return call(pHeap, args);
    }
private:
    std::function<ConstantSP(vector<ConstantSP>&)> func_;
    int minParamNum_;
    int maxParamNum_;
    bool hasReturnValue_;
};
