/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.cassandra.distributed.api;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * A table of data representing a complete query result.
 * <p>
 * A <code>QueryResult</code> is different from {@link java.sql.ResultSet} in several key ways:
 *
 * <ul>
 *     <li>represents a complete result rather than a cursor</li>
 *     <li>returns a {@link Row} to access the current row of data</li>
 *     <li>relies on object pooling; {@link #hasNext()} may return the same object just with different data, accessing a
 *     {@link Row} from a previous {@link #hasNext()} call has undefined behavior.</li>
 *     <li>includes {@link #filter(Predicate)}, this will do client side filtering since Apache Cassandra is more
 *     restrictive on server side filtering</li>
 * </ul>
 *
 * <h2>Unsafe patterns</h2>
 * <p>
 * Below are a few unsafe patterns which may lead to unexpected results
 *
 * <code>{@code
 * while (rs.hasNext()) {
 *   list.add(rs.next());
 * }
 * }</code>
 *
 * <code>{@code
 * rs.forEach(list::add)
 * }</code>
 * <p>
 * Both cases have the same issue; reference to a row from a previous call to {@link #hasNext()}.  Since the same {@link Row}
 * object can be used accross different calls to {@link #hasNext()} this would mean any attempt to access after the fact
 * points to newer data.  If this behavior is not desirable and access is needed between calls, then {@link Row#copy()}
 * should be used; this will clone the {@link Row} and return a new object pointing to the same data.
 */
public class SimpleQueryResult implements QueryResult
{
    private final String[] names;
    private final Object[][] results;
    private final List<String> warnings;
    private final Predicate<Row> filter;
    private final Row row;
    private int offset = -1;

    public SimpleQueryResult(String[] names, Object[][] results)
    {
        this(names, results, Collections.emptyList());
    }

    public SimpleQueryResult(String[] names, Object[][] results, List<String> warnings)
    {
        this.names = Objects.requireNonNull(names, "names");
        this.results = results;
        this.warnings = Objects.requireNonNull(warnings, "warnings");
        this.row = new Row(names);
        this.filter = ignore -> true;
    }

    private SimpleQueryResult(String[] names, Object[][] results, Predicate<Row> filter, int offset)
    {
        this.names = names;
        this.results = results;
        this.warnings = Collections.emptyList();
        this.filter = filter;
        this.offset = offset;
        this.row = new Row(names);
    }

    public List<String> names()
    {
        return Collections.unmodifiableList(Arrays.asList(names));
    }

    @Override
    public List<String> warnings()
    {
        return Collections.unmodifiableList(warnings);
    }

    public SimpleQueryResult filter(Predicate<Row> fn)
    {
        return new SimpleQueryResult(names, results, filter.and(fn), offset);
    }

    /**
     * Reset the cursor to the start of the query result; if the query result has not been iterated, this has no effect.
     */
    public void reset()
    {
        offset = -1;
        row.setResults(null);
    }

    /**
     * Get all rows as a 2d array.  Any calls to {@link #filter(Predicate)} will be ignored and the array returned will
     * be the full set from the query.
     */
    public Object[][] toObjectArrays()
    {
        return results;
    }

    @Override
    public boolean hasNext()
    {
        if (results == null)
            return false;
        while ((offset += 1) < results.length)
        {
            row.setResults(results[offset]);
            if (filter.test(row))
            {
                return true;
            }
        }
        row.setResults(null);
        return false;
    }

    @Override
    public Row next()
    {
        // no null check needed for results since offset only increments IFF results is not null
        if (offset < 0 || offset >= results.length)
            throw new NoSuchElementException();
        return row;
    }

    @Override
    public String toString() {
        if (results == null)
            return "[]";
        return Stream.of(results)
                .map(Arrays::toString)
                .collect(Collectors.joining(",", "[", "]"));
    }
}
