package click.kamil.springstatemachineexporter.analysis.model;

/**
 * Stable identity keys for {@link EntryPoint} used by scoping, merge, and semantic dedup.
 */
public final class EntryPointKeys {

    private EntryPointKeys() {
    }

    /**
     * Prefer human-readable entry name (REST path / topic); otherwise {@code class#method}.
     */
    public static String of(EntryPoint entryPoint) {
        if (entryPoint == null) {
            return "";
        }
        if (entryPoint.getName() != null && !entryPoint.getName().isBlank()) {
            return entryPoint.getName();
        }
        if (entryPoint.getClassName() != null && entryPoint.getMethodName() != null) {
            return entryPoint.getClassName() + "#" + entryPoint.getMethodName();
        }
        return "";
    }

    /**
     * Entry identity for a call chain: entry point when present, otherwise first hop / trigger site.
     */
    public static String of(CallChain chain) {
        if (chain == null) {
            return "";
        }
        String fromEntry = of(chain.getEntryPoint());
        if (!fromEntry.isEmpty()) {
            return fromEntry;
        }
        if (chain.getMethodChain() != null && !chain.getMethodChain().isEmpty()) {
            return normalizeMethodHop(chain.getMethodChain().get(0));
        }
        TriggerPoint trigger = chain.getTriggerPoint();
        if (trigger != null && trigger.getClassName() != null && trigger.getMethodName() != null) {
            return trigger.getClassName() + "#" + trigger.getMethodName();
        }
        return "";
    }

    /** Converts {@code com.example.Foo.bar} hop form to {@code com.example.Foo#bar}. */
    public static String normalizeMethodHop(String hop) {
        if (hop == null || hop.isBlank()) {
            return "";
        }
        int lastDot = hop.lastIndexOf('.');
        if (lastDot <= 0 || lastDot >= hop.length() - 1) {
            return hop;
        }
        return hop.substring(0, lastDot) + "#" + hop.substring(lastDot + 1);
    }
}
