package io.crate.planner.symbol;

import io.crate.metadata.FunctionInfo;
import org.cratedb.DataType;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;

import java.io.IOException;

public class Function extends ValueSymbol {

    public static final SymbolFactory<Function> FACTORY = new SymbolFactory<Function>() {
        @Override
        public Function newInstance() {
            return new Function();
        }
    };

    private FunctionInfo info;

    public Function(FunctionInfo info) {
        this.info = info;
    }

    public Function() {

    }

    @Override
    public DataType valueType() {
        return info.returnType();
    }

    @Override
    public SymbolType symbolType() {
        return SymbolType.FUNCTION;
    }

    @Override
    public <C, R> R accept(SymbolVisitor<C, R> visitor, C context) {
        return visitor.visitFunction(this, context);
    }

    @Override
    public void readFrom(StreamInput in) throws IOException {
        info = new FunctionInfo();
        info.readFrom(in);
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        info.writeTo(out);
    }
}

@@ -95,16 +95,63 @@
 taType;%0A
+import org.elasticsearch.common.Preconditions;%0A
 import o
@@ -281,16 +281,67 @@
 ception;
+%0Aimport java.util.ArrayList;%0Aimport java.util.List;
 %0A%0Apublic
@@ -580,16 +580,57 @@
     %7D;%0A%0A
+    private List%3CValueSymbol%3E arguments;%0A
     priv
@@ -694,69 +694,304 @@
 info
-) %7B%0A        this.info = info;%0A    %7D%0A%0A    public Function() %7B%0A
+, List%3CValueSymbol%3E arguments) %7B%0A        Preconditions.checkArgument(arguments.size() == info.ident().argumentTypes().size());%0A        this.info = info;%0A        this.arguments = arguments;%0A    %7D%0A%0A    public Function() %7B%0A%0A    %7D%0A%0A    public List%3CValueSymbol%3E arguments() %7B%0A        return arguments;
 %0A   
@@ -1462,123 +1462,483 @@
 n);%0A
-    %7D%0A%0A    @Override%0A    public void writeTo(StreamOutput out) throws IOException %7B%0A        info.writeTo(out);
+%0A        int numArguments = in.readVInt();%0A        arguments = new ArrayList%3C%3E(numArguments);%0A        for (int i = 0; i %3C numArguments; i++) %7B%0A            arguments.add((ValueSymbol)Symbol.fromStream(in));%0A        %7D%0A    %7D%0A%0A    @Override%0A    public void writeTo(StreamOutput out) throws IOException %7B%0A        info.writeTo(out);%0A        out.writeVInt(arguments.size());%0A        for (ValueSymbol argument : arguments) %7B%0A            Symbol.toStream(argument, out);%0A        %7D
 %0A    %7D%0A%7D
 %0A
@@ -1936,9 +1936,8 @@
 %0A    %7D%0A%7D
-%0A

add arguments to Function (symbol)