package ch.usi.inf.sp.callgraph.renderer;

import ch.usi.inf.sp.callgraph.ClassType;

import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

public class DotClassNode implements DotNode {

    private final ClassType type;

    public DotClassNode(ClassType type) {
        this.type = type;
    }

    public boolean isResolved() {
        return type.isResolved();
    }

    public ClassType getType() {
        return this.type;
    }

    public String getStyle() {
        return type.isInterface() ? "dotted" : type.isAbstract() ? "dashed" : "solid";
    }

    @Override
    public Map<String, String> getProperties() {
        final String className = type.getInternalName();

        if (!isResolved()) {
            // "External" classes (like java.lang.Math) are just ellipsis
            return Map.of(
                    "shape", "ellipse",
                    "style", getStyle(),
                    "label", className
            );
        }

        final String methods = type.getMethods().stream()
                .map(MethodAdapter::new)
                .map(MethodLike::prettyName)
                .collect(Collectors.joining("\\n"));

        return Map.of(
                "shape", "record",
                "style", getStyle(),
                "label", DotNode.recordSplit(className, methods)
        );
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DotClassNode that = (DotClassNode) o;
        return Objects.equals(type, that.type);
    }

    @Override
    public int hashCode() {
        return Objects.hash(type);
    }
}
