package com.jscape.util.io;

import com.jscape.util.ExceptionTools;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

import static com.jscape.util.Parameters.assertNotNull;

/**
 * @author Alex Usun
 */
public class ComponentReadableFile<T>
        implements ReadableFile<T> {

    private final DataSource source;
    private final List<DataReader<T>> readers;

    public ComponentReadableFile(DataSource source, List<DataReader<T>> readers) {
        assertNotNull(source);
        this.source = source;

        assertNotNull(readers);
        this.readers = readers;
    }

    @SafeVarargs
    public ComponentReadableFile(DataSource source, DataReader<T>... readers) {
        this(source, Arrays.asList(readers));
    }

    public boolean readAllowed() {
        return this.source.readAllowed();
    }

    public T read()
            throws IOException {
        Exception error = null;

        for (DataReader<T> reader : this.readers) {
            try {
                return read(reader);
            } catch (Exception e) {
                error = e;
            }
        }

        throw ExceptionTools.ioException(error);
    }

    private T read(DataReader<T> reader)
            throws IOException {
        try (InputStream in = this.source.getInputStream()) {
            return reader.read(in);
        }
    }

    @Override
    public String toString() {
        return "ComponentReadableFile {"
               + "source=" + this.source
               + ", readers=" + this.readers
               + '}';
    }
}
