package function.builtin.math;

import java.math.BigInteger;

import function.ArgumentValidator;
import function.FunctionNames;
import function.LispFunction;
import sexpression.Cons;
import sexpression.LispNumber;

@FunctionNames({ "-" })
public class MINUS extends LispFunction {

    private ArgumentValidator argumentValidator;
    private MathFunction mathFunction;

    public MINUS(String name) {
        this.argumentValidator = new ArgumentValidator(name);
        this.argumentValidator.setMinimumNumberOfArguments(1);
        this.argumentValidator.setEveryArgumentExpectedType(LispNumber.class);
        this.mathFunction = new MathFunction(this::additiveInverse, this::subtract);
    }

    @Override
    public LispNumber call(Cons argumentList) {
        argumentValidator.validate(argumentList);

        return mathFunction.callTailRecursive(argumentList);
    }

    private LispNumber additiveInverse(LispNumber number) {
        return new LispNumber(BigInteger.ZERO.subtract(number.getValue()));
    }

    private LispNumber subtract(LispNumber number1, LispNumber number2) {
        return new LispNumber(number1.getValue().subtract(number2.getValue()));
    }

}
