/*
 * 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.asterix.runtime.evaluators.functions;

import static org.apache.asterix.om.types.EnumDeserializer.ATYPETAGDESERIALIZER;

import org.apache.asterix.builders.OrderedListBuilder;
import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
import org.apache.asterix.om.base.AMutableDouble;
import org.apache.asterix.om.base.AMutableInt64;
import org.apache.asterix.om.typecomputer.impl.ArrayRangeTypeComputer;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.api.exceptions.SourceLocation;
import org.apache.hyracks.data.std.api.IPointable;
import org.apache.hyracks.data.std.primitive.TaggedValuePointable;
import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;

/**
 * <pre>
 * array_range(start_num, end_num, step_num?) returns a new ordered list, list of long items or double items
 * depending on the supplied arguments. One floating-point arg will make it a list of double items. step_num is optional
 * where the default is 1. It returns an empty list for arguments like:
 * array_range(2, 20, -2), array_range(10, 3, 4) and array_range(1,6,0) where it cannot determine a proper sequence.
 *
 * It throws an error at compile time if the number of arguments < 2 or > 3
 *
 * It returns in order:
 * 1. missing, if any argument is missing.
 * 2. null, if any argument is null or they are not numeric or they are NaN +-INF.
 * 3. otherwise, a new list.
 *
 * </pre>
*/

public class ArrayRangeEvaluator extends AbstractScalarEval {
    private final OrderedListBuilder listBuilder;
    private final ArrayBackedValueStorage storage;
    private final IScalarEvaluator startNumEval;
    private final TaggedValuePointable start;
    private final IScalarEvaluator endNumEval;
    private final TaggedValuePointable end;
    private final AMutableDouble aDouble;
    private final AMutableInt64 aLong;
    private IScalarEvaluator stepNumEval;
    private TaggedValuePointable step;

    ArrayRangeEvaluator(IScalarEvaluatorFactory[] args, IEvaluatorContext ctx, SourceLocation sourceLocation,
            FunctionIdentifier functionIdentifier) throws HyracksDataException {
        super(sourceLocation, functionIdentifier);
        storage = new ArrayBackedValueStorage();
        start = new TaggedValuePointable();
        end = new TaggedValuePointable();
        startNumEval = args[0].createScalarEvaluator(ctx);
        endNumEval = args[1].createScalarEvaluator(ctx);
        listBuilder = new OrderedListBuilder();
        aDouble = new AMutableDouble(0);
        aLong = new AMutableInt64(0);
        if (args.length == 3) {
            stepNumEval = args[2].createScalarEvaluator(ctx);
            step = new TaggedValuePointable();
        }
    }

    @Override
    public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
        startNumEval.evaluate(tuple, start);
        endNumEval.evaluate(tuple, end);
        if (stepNumEval != null) {
            stepNumEval.evaluate(tuple, step);
        }

        if (PointableHelper.checkAndSetMissingOrNull(result, start, end, step)) {
            return;
        }

        String n = funID.getName();
        ATypeTag startTag = ATYPETAGDESERIALIZER.deserialize(start.getTag());
        ATypeTag endTag = ATYPETAGDESERIALIZER.deserialize(end.getTag());
        ATypeTag stepTag = ATypeTag.INTEGER;
        double stepNum = 1;
        if (stepNumEval != null) {
            stepNumEval.evaluate(tuple, step);
            stepTag = ATYPETAGDESERIALIZER.deserialize(step.getTag());
            if (!ATypeHierarchy.isCompatible(ATypeTag.DOUBLE, stepTag)) {
                PointableHelper.setNull(result);
                return;
            }
            stepNum = ATypeHierarchy.getDoubleValue(n, 2, step.getByteArray(), step.getStartOffset());
        }

        if (!ATypeHierarchy.isCompatible(ATypeTag.DOUBLE, startTag) || Double.isNaN(stepNum)
                || !ATypeHierarchy.isCompatible(ATypeTag.DOUBLE, endTag) || Double.isInfinite(stepNum)) {
            PointableHelper.setNull(result);
            return;
        }

        ISerializerDeserializer serde;
        if (ATypeHierarchy.canPromote(startTag, ATypeTag.BIGINT) && ATypeHierarchy.canPromote(endTag, ATypeTag.BIGINT)
                && ATypeHierarchy.canPromote(stepTag, ATypeTag.BIGINT)) {
            // all 3 numbers are whole numbers
            serde = SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64);
            long startNum = ATypeHierarchy.getLongValue(n, 0, start.getByteArray(), start.getStartOffset());
            long endNum = ATypeHierarchy.getLongValue(n, 1, end.getByteArray(), end.getStartOffset());
            listBuilder.reset(ArrayRangeTypeComputer.LONG_LIST);
            while ((startNum < endNum && stepNum > 0) || (startNum > endNum && stepNum < 0)) {
                aLong.setValue(startNum);
                storage.reset();
                serde.serialize(aLong, storage.getDataOutput());
                listBuilder.addItem(storage);
                startNum += stepNum;
            }
        } else {
            // one number is a floating-point number
            serde = SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADOUBLE);
            double startNum = ATypeHierarchy.getDoubleValue(n, 0, start.getByteArray(), start.getStartOffset());
            double endNum = ATypeHierarchy.getDoubleValue(n, 1, end.getByteArray(), end.getStartOffset());
            if (Double.isNaN(startNum) || Double.isInfinite(startNum) || Double.isNaN(endNum)
                    || Double.isInfinite(endNum)) {
                PointableHelper.setNull(result);
                return;
            }
            listBuilder.reset(ArrayRangeTypeComputer.DOUBLE_LIST);
            while ((startNum < endNum && stepNum > 0) || (startNum > endNum && stepNum < 0)) {
                aDouble.setValue(startNum);
                storage.reset();
                serde.serialize(aDouble, storage.getDataOutput());
                listBuilder.addItem(storage);
                startNum += stepNum;
            }
        }

        storage.reset();
        listBuilder.write(storage.getDataOutput(), true);
        result.set(storage);
    }
}
