package ctbrec.recorder.download;

import java.io.IOException;
import java.time.Instant;
import java.util.concurrent.ExecutorService;

import ctbrec.Config;
import ctbrec.Model;
import ctbrec.Settings;
import ctbrec.UnknownModel;
import ctbrec.recorder.download.hls.CombinedSplittingStrategy;
import ctbrec.recorder.download.hls.NoopSplittingStrategy;
import ctbrec.recorder.download.hls.SizeSplittingStrategy;
import ctbrec.recorder.download.hls.TimeSplittingStrategy;

public abstract class AbstractDownload implements Download {

    protected Instant startTime;
    protected Instant rescheduleTime = Instant.now();
    protected Model model = new UnknownModel();

    protected transient Config config;
    protected transient SplittingStrategy splittingStrategy;
    protected transient ExecutorService downloadExecutor;

    @Override
    public void init(Config config, Model model, Instant startTime, ExecutorService executorService) throws IOException {
        this.config = config;
        this.model = model;
        this.startTime = startTime;
        this.downloadExecutor = executorService;
        splittingStrategy = initSplittingStrategy(config.getSettings());
    }

    @Override
    public Instant getStartTime() {
        return startTime;
    }

    @Override
    public Instant getRescheduleTime() {
        return rescheduleTime;
    }

    protected SplittingStrategy initSplittingStrategy(Settings settings) {
        SplittingStrategy strategy;
        switch (settings.splitStrategy) {
        case TIME:
            strategy = new TimeSplittingStrategy();
            break;
        case SIZE:
            strategy = new SizeSplittingStrategy();
            break;
        case TIME_OR_SIZE:
            SplittingStrategy timeSplittingStrategy = new TimeSplittingStrategy();
            SplittingStrategy sizeSplittingStrategy = new SizeSplittingStrategy();
            strategy = new CombinedSplittingStrategy(timeSplittingStrategy, sizeSplittingStrategy);
            break;
        case DONT:
        default:
            strategy = new NoopSplittingStrategy();
            break;
        }
        strategy.init(settings);
        return strategy;
    }
}
