/*
 * 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 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);
        }
    }
}