package de.dhbwstuttgart.typeinference.unify.model;

import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class FunInterfaceType extends ReferenceType  {
    final List<UnifyType> intfArgTypes;
    final UnifyType intfReturnType;
    final List<String> generics;

    public FunInterfaceType(String name, TypeParams params, List<UnifyType> intfArgTypes, UnifyType intfReturnType, List<String> generics) {
        super(name, params);
        this.intfArgTypes = intfArgTypes;
        this.intfReturnType = intfReturnType;
        this.generics = generics;
    }

    public List<UnifyType> getFunctionalInterfaceTypeArguments(UnifyType t) {
        if (t instanceof FunNType) {
            var ret = new ArrayList<UnifyType>();
            if (t.getTypeParams().size() > 0) {
                ret.add(t.getTypeParams().get(t.getTypeParams().size() - 1));
                ret.addAll(Arrays.asList(t.getTypeParams().get()).subList(0, t.getTypeParams().size() - 1));
            }
            return ret;
        }

        var args = new ArrayList<UnifyType>();
        args.add(intfReturnType);
        args.addAll(intfArgTypes);

        // TODO There might be a better way of dealing with this
        var i = 0;
        for (var generic : generics) {
            for (var j = 0; j < args.size(); j++) {
                if (args.get(j).getName().equals(generic))
                    args.set(j, t.getTypeParams().get(i));
            }
            i += 1;
        }

        return args;
    }
}
