package leigh.example.calcite.adapter;

import org.apache.calcite.DataContext;
import org.apache.calcite.linq4j.AbstractEnumerable2;
import org.apache.calcite.linq4j.Enumerable;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.schema.ScannableTable;
import org.apache.calcite.schema.impl.AbstractTable;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.util.Pair;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Spliterator;
import java.util.function.Consumer;

/**
 * Example of a read-only table.
 *
 * @author Alex Leigh
 */
public class ExampleTable extends AbstractTable implements ScannableTable {
    final List<RelDataType> types = new ArrayList<>();
    final ArrayList<Object[]> data = new ArrayList<>();

    public ExampleTable() {
        data.add(new String[]{"Hello World!"});
        data.add(new String[]{"Hello PNW!"});
    }

    @Override
    public RelDataType getRowType(RelDataTypeFactory typeFactory) {
        final List<String> names = new ArrayList<>();
        names.add("time");
        types.add(typeFactory.createSqlType(SqlTypeName.VARCHAR));
        return typeFactory.createStructType(Pair.zip(names, types));
    }

    @Override
    public Enumerable<Object[]> scan(DataContext root) {
        return new AbstractEnumerable2<>() {
            @NotNull
            @Override
            public Iterator<Object[]> iterator() {
                return data.iterator();
            }

            @Override
            public void forEach(Consumer<? super Object[]> action) {
                super.forEach(action);
            }

            @Override
            public Spliterator<Object[]> spliterator() {
                return super.spliterator();
            }
        };
    }
}
