/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed 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 com.android.server.display.whitebalance;

import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.utils.RollingBuffer;

import java.io.PrintWriter;
import java.util.Arrays;

/**
 * The DisplayWhiteBalanceController uses the AmbientFilter to average ambient changes over time,
 * filter out the noise, and arrive at an estimate of the actual value.
 *
 * When the DisplayWhiteBalanceController detects a change in ambient brightness or color
 * temperature, it passes it to the AmbientFilter, and when it needs the actual ambient value, it
 * asks it for an estimate.
 *
 * Implementations:
 * - {@link WeightedMovingAverageAmbientFilter}
 *   A weighted average prioritising recent changes.
 */
abstract class AmbientFilter {

    protected static final boolean DEBUG = false; // Enable for verbose logs.

    protected final String mTag;
    protected boolean mLoggingEnabled;

    // How long ambient value changes are kept and taken into consideration.
    private final int mHorizon; // Milliseconds

    private final RollingBuffer mBuffer;

    /**
     * @param tag
     *      The tag used for dumping and logging.
     * @param horizon
     *      How long ambient value changes are kept and taken into consideration.
     *
     * @throws IllegalArgumentException
     *      - horizon is not positive.
     */
    AmbientFilter(String tag, int horizon) {
        validateArguments(horizon);
        mTag = tag;
        mLoggingEnabled = false;
        mHorizon = horizon;
        mBuffer = new RollingBuffer();
    }

    /**
     * Add an ambient value change.
     *
     * @param time
     *      The time.
     * @param value
     *      The ambient value.
     *
     * @return Whether the method succeeded or not.
     */
    public boolean addValue(long time, float value) {
        if (value < 0.0f) {
            return false;
        }
        truncateOldValues(time);
        if (mLoggingEnabled) {
            Slog.d(mTag, "add value: " + value + " @ " + time);
        }
        mBuffer.add(time, value);
        return true;
    }

    /**
     * Get an estimate of the actual ambient color temperature.
     *
     * @param time
     *      The time.
     *
     * @return An estimate of the actual ambient color temperature.
     */
    public float getEstimate(long time) {
        truncateOldValues(time);
        final float value = filter(time, mBuffer);
        if (mLoggingEnabled) {
            Slog.d(mTag, "get estimate: " + value + " @ " + time);
        }
        return value;
    }

    /**
     * Clears the filter state.
     */
    public void clear() {
        mBuffer.clear();
    }

    /**
     * Enable/disable logging.
     *
     * @param loggingEnabled
     *      Whether logging is on/off.
     *
     * @return Whether the method succeeded or not.
     */
    public boolean setLoggingEnabled(boolean loggingEnabled) {
        if (mLoggingEnabled == loggingEnabled) {
            return false;
        }
        mLoggingEnabled = loggingEnabled;
        return true;
    }

    /**
     * Dump the state.
     *
     * @param writer
     *      The PrintWriter used to dump the state.
     */
    public void dump(PrintWriter writer) {
        writer.println("  " + mTag);
        writer.println("    mLoggingEnabled=" + mLoggingEnabled);
        writer.println("    mHorizon=" + mHorizon);
        writer.println("    mBuffer=" + mBuffer);
    }

    private void validateArguments(int horizon) {
        if (horizon <= 0) {
            throw new IllegalArgumentException("horizon must be positive");
        }
    }

    private void truncateOldValues(long time) {
        final long minTime = time - mHorizon;
        mBuffer.truncate(minTime);
    }

    protected abstract float filter(long time, RollingBuffer buffer);

    /**
     * A weighted average prioritising recent changes.
     */
    @VisibleForTesting
    public static class WeightedMovingAverageAmbientFilter extends AmbientFilter {

        // How long the latest ambient value change is predicted to last.
        private static final int PREDICTION_TIME = 100; // Milliseconds

        // Recent changes are prioritised by integrating their duration over y = x + mIntercept
        // (the higher it is, the less prioritised recent changes are).
        private final float mIntercept;

        /**
         * @param tag
         *      The tag used for dumping and logging.
         * @param horizon
         *      How long ambient value changes are kept and taken into consideration.
         * @param intercept
         *      Recent changes are prioritised by integrating their duration over y = x + intercept
         *      (the higher it is, the less prioritised recent changes are).
         *
         * @throws IllegalArgumentException
         *      - horizon is not positive.
         *      - intercept is NaN or negative.
         */
        WeightedMovingAverageAmbientFilter(String tag, int horizon, float intercept) {
            super(tag, horizon);
            validateArguments(intercept);
            mIntercept = intercept;
        }

        /**
         * See {@link AmbientFilter#dump base class}.
         */
        @Override
        public void dump(PrintWriter writer) {
            super.dump(writer);
            writer.println("    mIntercept=" + mIntercept);
        }

        // Normalise the times to [t1=0, t2, ..., tN, now + PREDICTION_TIME], so the first change
        // starts at 0 and the last change is predicted to last a bit, and divide them by 1000 as
        // milliseconds are high enough to overflow.
        // The weight of the value from t[i] to t[i+1] is the area under (A.K.A. the integral of)
        // y = x + mIntercept from t[i] to t[i+1].
        @Override
        protected float filter(long time, RollingBuffer buffer) {
            if (buffer.isEmpty()) {
                return -1.0f;
            }
            float total = 0.0f;
            float totalWeight = 0.0f;
            final float[] weights = getWeights(time, buffer);
            if (DEBUG && mLoggingEnabled) {
                Slog.v(mTag, "filter: " + buffer + " => " + Arrays.toString(weights));
            }
            for (int i = 0; i < weights.length; i++) {
                final float value = buffer.getValue(i);
                final float weight = weights[i];
                total += weight * value;
                totalWeight += weight;
            }
            if (totalWeight == 0.0f) {
                return buffer.getValue(buffer.size() - 1);
            }
            return total / totalWeight;
        }

        private void validateArguments(float intercept) {
            if (Float.isNaN(intercept) || intercept < 0.0f) {
                throw new IllegalArgumentException("intercept must be a non-negative number");
            }
        }

        private float[] getWeights(long time, RollingBuffer buffer) {
            float[] weights = new float[buffer.size()];
            final long startTime = buffer.getTime(0);
            float previousTime = 0.0f;
            for (int i = 1; i < weights.length; i++) {
                final float currentTime = (buffer.getTime(i) - startTime) / 1000.0f;
                final float weight = calculateIntegral(previousTime, currentTime);
                weights[i - 1] = weight;
                previousTime = currentTime;
            }
            final float lastTime = (time + PREDICTION_TIME - startTime) / 1000.0f;
            final float lastWeight = calculateIntegral(previousTime, lastTime);
            weights[weights.length - 1] = lastWeight;
            return weights;
        }

        private float calculateIntegral(float from, float to) {
            return antiderivative(to) - antiderivative(from);
        }

        private float antiderivative(float x) {
            // f(x) = x + c => F(x) = 1/2 * x^2 + c * x
            return 0.5f * x * x + mIntercept * x;
        }

    }

}
