package ru.kirillius.pf.sdn.api.flow;

import lombok.Getter;
import ru.kirillius.pf.sdn.api.Networking.NetworkScope;

import java.util.ArrayList;
import java.util.List;

public class ExecutionInfoEntry {

    public ExecutionInfoEntry(NetworkScope result, NetworkScope source) {
        this.resultingScope = result;
        added = new NetworkScope();
        removed = new NetworkScope();

        var compareSubnets = diff(source.getSubnets(), result.getSubnets());
        var compareDomains = diff(source.getDomains(), result.getDomains());
        var compareASN = diff(source.getASN(), result.getASN());
        var compareAutoResolved = diff(source.getResolveDomains(), result.getResolveDomains());

        added.getSubnets().addAll(compareSubnets.added);
        added.getDomains().addAll(compareDomains.added);
        added.getASN().addAll(compareASN.added);
        added.getResolveDomains().addAll(compareAutoResolved.added);
        removed.getSubnets().addAll(compareSubnets.removed);
        removed.getDomains().addAll(compareDomains.removed);
        removed.getASN().addAll(compareASN.removed);
        removed.getResolveDomains().addAll(compareAutoResolved.removed);

    }

    private <T> CompareResult<T> diff(List<T> source, List<T> target) {
        var added = new ArrayList<T>();
        var removed = new ArrayList<T>();

        source.forEach(item -> {
            if (!target.contains(item)) {
                removed.add(item);
            }
        });
        target.forEach(item -> {
            if (!source.contains(item)) {
                added.add(item);
            }
        });
        return new CompareResult<>(added, removed);
    }

    private record CompareResult<T>(List<T> added, List<T> removed) {
    }

    @Getter
    private final NetworkScope resultingScope;

    @Getter
    private final NetworkScope added;

    @Getter
    private final NetworkScope removed;

}
