package de.renew.formalism.function;

import java.lang.reflect.Array;

import de.renew.expression.Function;
import de.renew.unify.Impossible;
import de.renew.unify.Tuple;
import de.renew.util.Value;

/**
 * A function that writes a value to an array at a specified index.
 */
public final class ArrayWriteFunction implements Function {
    /**
     * The shared instance of the array write function.
     */
    public static final Function FUN = new ArrayWriteFunction();

    private ArrayWriteFunction() {}

    @Override
    public Object function(Object param) throws Impossible {
        Tuple tuple = (Tuple) param;
        if (tuple.getArity() != 3) {
            throw new Impossible();
        }

        try {
            Object arr = tuple.getComponent(0);
            Object idx = Value.unvalueAndCast(tuple.getComponent(1), Integer.TYPE);
            Object value =
                Value.unvalueAndCast(tuple.getComponent(2), arr.getClass().getComponentType());

            Array.set(arr, (Integer) idx, value);

            return value;
        } catch (Exception e) {
            throw new Impossible("Exception occurred during method call: " + e);
        }
    }
}