/*
 * 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.tinkerpop.gremlin.process.traversal.step.map;

import org.apache.tinkerpop.gremlin.util.NumberHelper;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.util.function.MeanNumberSupplier;

import java.io.Serializable;
import java.util.EnumSet;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;

import static org.apache.tinkerpop.gremlin.util.NumberHelper.div;
import static org.apache.tinkerpop.gremlin.util.NumberHelper.mul;

/**
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 * @author Daniel Kuppitz (http://gremlin.guru)
 */
public final class MeanGlobalStep<S extends Number, E extends Number> extends ReducingBarrierStep<S, E> {

    private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(TraverserRequirement.OBJECT, TraverserRequirement.BULK);

    public MeanGlobalStep(final Traversal.Admin traversal) {
        super(traversal);
        this.setSeedSupplier((Supplier) MeanNumberSupplier.instance());
        this.setReducingBiOperator(MeanGlobalBiOperator.INSTANCE);
    }

    @Override
    public void processAllStarts() {
        if (this.starts.hasNext())
            super.processAllStarts();
    }

    @Override
    public E projectTraverser(final Traverser.Admin<S> traverser) {
        return (E) new MeanNumber(traverser.get(), traverser.bulk());
    }

    @Override
    public Set<TraverserRequirement> getRequirements() {
        return REQUIREMENTS;
    }

    @Override
    public E generateFinalResult(final E meanNumber) {
        return (E) ((MeanNumber) meanNumber).getFinal();
    }

    /////

    public static final class MeanGlobalBiOperator<S extends Number> implements BinaryOperator<S>, Serializable {

        private static final MeanGlobalBiOperator INSTANCE = new MeanGlobalBiOperator();

        @Override
        public S apply(final S mutatingSeed, final S number) {
            if (mutatingSeed instanceof MeanNumber) {
                return (number instanceof MeanNumber) ?
                        (S) ((MeanNumber) mutatingSeed).add((MeanNumber) number) :
                        (S) ((MeanNumber) mutatingSeed).add(number, 1l);
            } else {
                return (number instanceof MeanNumber) ?
                        (S) ((MeanNumber) number).add(mutatingSeed, 1l) :
                        (S) new MeanNumber(number, 1l).add(mutatingSeed, 1l);
            }
        }
    }

    public static final class MeanNumber extends Number implements Comparable<Number> {

        private long count;
        private Number sum;

        public MeanNumber() {
            this(0, 0);
        }

        public MeanNumber(final Number number, final long count) {
            this.count = count;
            this.sum = mul(number, count);
        }

        public MeanNumber add(final Number amount, final long count) {
            this.count += count;
            this.sum = NumberHelper.add(sum, mul(amount, count));
            return this;
        }

        public MeanNumber add(final MeanNumber other) {
            this.count += other.count;
            this.sum = NumberHelper.add(sum, other.sum);
            return this;
        }

        @Override
        public int intValue() {
            return div(this.sum, this.count).intValue();
        }

        @Override
        public long longValue() {
            return div(this.sum, this.count).longValue();
        }

        @Override
        public float floatValue() {
            return div(this.sum, this.count, true).floatValue();
        }

        @Override
        public double doubleValue() {
            return div(this.sum, this.count, true).doubleValue();
        }

        @Override
        public String toString() {
            return getFinal().toString();
        }

        @Override
        public int compareTo(final Number number) {
            // TODO: NumberHelper should provide a compareTo() implementation
            return Double.valueOf(this.doubleValue()).compareTo(number.doubleValue());
        }

        @Override
        public boolean equals(final Object object) {
            return object instanceof Number && Double.valueOf(this.doubleValue()).equals(((Number) object).doubleValue());
        }

        @Override
        public int hashCode() {
            return Double.valueOf(this.doubleValue()).hashCode();
        }

        public Number getFinal() {
            return div(this.sum, this.count, true);
        }
    }
}