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

import lombok.*;
import ru.kirillius.pf.sdn.api.Networking.NetworkScope;
import ru.kirillius.pf.sdn.entity.PipelineConfig;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

@RequiredArgsConstructor()
public class Flow {
    @Getter
    private final PipelineConfig config;
    private final List<FlowAction> actions;

    private final AtomicBoolean running = new AtomicBoolean(false);
    private final AtomicBoolean interrupted = new AtomicBoolean(false);

    private AtomicInteger currentStep = new AtomicInteger(0);

    public boolean isRunning() {
        return running.get();
    }

    public int getStepCount() {
        return actions.size();
    }

    public int getCurrentStep() {
        return currentStep.get();
    }

    public void interrupt() {
        interrupted.set(false);
    }

    private List<ExecutionInfoEntry> executionInfo = new ArrayList<>();

    public void execute() {
        interrupted.set(false);
        running.set(true);
        currentStep.set(0);
        try {
            var scope = new AtomicReference<>(new NetworkScope());
            actions.forEach(action -> {
                if (interrupted.get()) {
                    throw new RuntimeException("Interrupted");
                }
                currentStep.incrementAndGet();
                scope.set(action.apply(scope.get()));
            });
        } finally {
            interrupted.set(false);
            running.set(false);
        }
    }
}
