package de.dhbwstuttgart.target.tree;

import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.target.tree.expression.TargetBlock;
import de.dhbwstuttgart.target.tree.type.TargetType;

import java.util.List;
import java.util.Set;

public interface TargetStructure {
    int modifiers();
    JavaClassName qualifiedName();
    TargetType superType();
    Set<TargetGeneric> generics();
    Set<TargetGeneric> txGenerics();
    List<TargetType> implementingInterfaces();
    List<TargetConstructor> constructors();

    TargetMethod staticConstructor();

    List<TargetField> fields();
    List<TargetMethod> methods();

    default String getName() {
        return qualifiedName().toString().replaceAll("\\.", "/");
    }

    // These methods are only meant to be used for test cases, a Class record should be immutable!
    default void addMethod(int access, String name, Set<TargetGeneric> generics, List<MethodParameter> parameterTypes, TargetType returnType, TargetBlock block) {
        this.methods().add(new TargetMethod(access, name, block, new TargetMethod.Signature(generics, parameterTypes, returnType), null));
    }

    default void addMethod(int access, String name, List<MethodParameter> parameterTypes, TargetType returnType, TargetBlock block) {
        addMethod(access, name, Set.of(), parameterTypes, returnType, block);
    }

    default void addConstructor(int access, Set<TargetGeneric> generics, List<MethodParameter> paramterTypes, TargetBlock block) {
        this.constructors().add(new TargetConstructor(access, generics, Set.of(), paramterTypes, List.of(), block, null));
    }

    default void addConstructor(int access, List<MethodParameter> paramterTypes, TargetBlock block) {
        addConstructor(access, Set.of(), paramterTypes, block);
    }
}
