<commit_before>package me.minidigger.voxelgameslib.phase;

import com.google.gson.annotations.Expose;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.inject.Inject;

import me.minidigger.voxelgameslib.VoxelGamesLib;
import me.minidigger.voxelgameslib.exception.DependencyGraphException;
import me.minidigger.voxelgameslib.exception.NoSuchFeatureException;
import me.minidigger.voxelgameslib.feature.Feature;
import me.minidigger.voxelgameslib.feature.FeatureCommandImplementor;
import me.minidigger.voxelgameslib.game.Game;
import me.minidigger.voxelgameslib.graph.Graph;

import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;

import co.aikar.commands.BukkitCommandManager;
import co.aikar.commands.BukkitRootCommand;
import lombok.extern.java.Log;

/**
 * Simple implementation of a {@link Phase}. Implements the necessary {@link Feature}-handling.
 */
@Log
public abstract class AbstractPhase implements Phase {

    @Inject
    private VoxelGamesLib main;
    @Inject
    private BukkitCommandManager commandManager;

    @Expose
    private String name;
    @Expose
    private String className;

    @Expose
    private boolean allowJoin;
    @Expose
    private boolean allowSpectate;

    @Nonnull
    @Expose
    private List<Feature> features = new ArrayList<>();


    private Game game;

    private Phase nextPhase;
    private boolean isRunning;
    private List<Feature> startedFeatures = new ArrayList<>();

    private LocalDateTime startTime;
    private Duration duration;

    public AbstractPhase() {
        className = getClass().getName().replace(PhaseTypeAdapter.DEFAULT_PATH + ".", "");
    }

    @Override
    public void setName(@Nonnull String name) {
        this.name = name;
    }

    @Nonnull
    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setNextPhase(Phase nextPhase) {
        this.nextPhase = nextPhase;
    }

    @Override
    public void setGame(@Nonnull Game game) {
        this.game = game;
    }

    @Override
    public void addFeature(@Nonnull Feature feature) {
        log.finer("add " + feature.getClass().getSimpleName() + " feature");
        features.add(feature);
    }

    @Nonnull
    @Override
    public Game getGame() {
        return game;
    }

    @Nonnull
    @Override
    @SuppressWarnings("unchecked")
    public <T extends Feature> T getFeature(@Nonnull Class<T> clazz) {
        return (T) features.stream().filter(f -> f.getClass().equals(clazz)).findFirst()
                .orElseThrow(() -> new NoSuchFeatureException(clazz));
    }

    @Nonnull
    @Override
    public List<Feature> getFeatures() {
        return features;
    }

    @Nonnull
    @Override
    public Phase getNextPhase() {
        return nextPhase;
    }

    @Override
    public void init() {
        log.finer("init " + getName());
    }

    @Override
    public void start() {
        if (!checkDependencies()) {
            game.abortGame();
            return;
        }
        // start timer
        startTime = LocalDateTime.now();

        log.finer("start phase" + getName());
        for (Feature feature : features) {
            if (game.isAborting()) {
                return;
            }
            log.finer("start " + feature.getName());
            try {
                feature.start();
            } catch (Exception ex) {
                log.severe("error while starting " + feature.getName());
                ex.printStackTrace();<commit_msg>next phase is actually nullable<commit_after>package me.minidigger.voxelgameslib.phase;

import com.google.gson.annotations.Expose;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;

import me.minidigger.voxelgameslib.VoxelGamesLib;
import me.minidigger.voxelgameslib.exception.DependencyGraphException;
import me.minidigger.voxelgameslib.exception.NoSuchFeatureException;
import me.minidigger.voxelgameslib.feature.Feature;
import me.minidigger.voxelgameslib.feature.FeatureCommandImplementor;
import me.minidigger.voxelgameslib.game.Game;
import me.minidigger.voxelgameslib.graph.Graph;

import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;

import co.aikar.commands.BukkitCommandManager;
import lombok.extern.java.Log;

/**
 * Simple implementation of a {@link Phase}. Implements the necessary {@link Feature}-handling.
 */
@Log
public abstract class AbstractPhase implements Phase {

    @Inject
    private VoxelGamesLib main;
    @Inject
    private BukkitCommandManager commandManager;

    @Expose
    private String name;
    @Expose
    private String className;

    @Expose
    private boolean allowJoin;
    @Expose
    private boolean allowSpectate;

    @Nonnull
    @Expose
    private List<Feature> features = new ArrayList<>();


    private Game game;

    @Nullable
    private Phase nextPhase;
    private boolean isRunning;
    private List<Feature> startedFeatures = new ArrayList<>();

    private LocalDateTime startTime;
    private Duration duration;

    public AbstractPhase() {
        className = getClass().getName().replace(PhaseTypeAdapter.DEFAULT_PATH + ".", "");
    }

    @Override
    public void setName(@Nonnull String name) {
        this.name = name;
    }

    @Nonnull
    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setNextPhase(Phase nextPhase) {
        this.nextPhase = nextPhase;
    }

    @Override
    public void setGame(@Nonnull Game game) {
        this.game = game;
    }

    @Override
    public void addFeature(@Nonnull Feature feature) {
        log.finer("add " + feature.getClass().getSimpleName() + " feature");
        features.add(feature);
    }

    @Nonnull
    @Override
    public Game getGame() {
        return game;
    }

    @Nonnull
    @Override
    @SuppressWarnings("unchecked")
    public <T extends Feature> T getFeature(@Nonnull Class<T> clazz) {
        return (T) features.stream().filter(f -> f.getClass().equals(clazz)).findFirst()
                .orElseThrow(() -> new NoSuchFeatureException(clazz));
    }

    @Nonnull
    @Override
    public List<Feature> getFeatures() {
        return features;
    }

    @Nullable
    @Override
    public Phase getNextPhase() {
        return nextPhase;
    }

    @Override
    public void init() {
        log.finer("init " + getName());
    }

    @Override
    public void start() {
        if (!checkDependencies()) {
            game.abortGame();
            return;
        }
        // start timer
        startTime = LocalDateTime.now();

        log.finer("start phase" + getName());
        for (Feature feature : features) {
            if (game.isAborting()) {
                return;
            }
            log.finer("start " + feature.getName());
            try {
                feature.start();
            } catch (Exception ex) {
                log.severe("error while starting " + feature.getName());
                ex.printStackTrace();
{'fraction_non_alphanumeric': 0.10431991440417279, 'fraction_numerical': 0.0, 'mean_word_length': 2.7672544080604533, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3402922', 'n_tokens_mistral': 2189, 'n_tokens_neox': 2118, 'n_words': 484}