/*
 * 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.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.util.Slog;

import com.android.internal.util.Preconditions;
import com.android.server.display.utils.History;

import java.io.PrintWriter;

/**
 * The DisplayWhiteBalanceController uses the AmbientSensor to detect changes in the ambient
 * brightness and color temperature.
 *
 * The AmbientSensor listens on an actual sensor, derives the ambient brightness or color
 * temperature from its events, and calls back into the DisplayWhiteBalanceController to report it.
 */
abstract class AmbientSensor {

    protected String mTag;
    protected boolean mLoggingEnabled;

    private final Handler mHandler;

    protected final SensorManager mSensorManager;
    protected Sensor mSensor;

    private boolean mEnabled;

    private int mRate; // Milliseconds

    // The total events count and the most recent events are kept for debugging purposes.
    private int mEventsCount;
    private static final int HISTORY_SIZE = 50;
    private History mEventsHistory;

    /**
     * @param tag
     *      The tag used for dumping and logging.
     * @param handler
     *      The handler used to determine which thread to run on.
     * @param sensorManager
     *      The sensor manager used to acquire necessary sensors.
     * @param rate
     *      The sensor rate.
     *
     * @throws IllegalArgumentException
     *      - rate is not positive.
     * @throws NullPointerException
     *      - handler is null;
     *      - sensorManager is null.
     * @throws IllegalStateException
     *      - Cannot find the necessary sensor.
     */
    AmbientSensor(String tag, @NonNull Handler handler, @NonNull SensorManager sensorManager,
            int rate) {
        validateArguments(handler, sensorManager, rate);
        mTag = tag;
        mLoggingEnabled = false;
        mHandler = handler;
        mSensorManager = sensorManager;
        mEnabled = false;
        mRate = rate;
        mEventsCount = 0;
        mEventsHistory = new History(HISTORY_SIZE);
    }

    /**
     * Enable/disable the sensor.
     *
     * @param enabled
     *      Whether the sensor should be on/off.
     *
     * @return Whether the method succeeded or not.
     */
    public boolean setEnabled(boolean enabled) {
        if (enabled) {
            return enable();
        } else {
            return disable();
        }
    }

    /**
     * Enable/disable logging.
     *
     * @param loggingEnabled
     *      Whether logging should be 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("    mHandler=" + mHandler);
        writer.println("    mSensorManager=" + mSensorManager);
        writer.println("    mSensor=" + mSensor);
        writer.println("    mEnabled=" + mEnabled);
        writer.println("    mRate=" + mRate);
        writer.println("    mEventsCount=" + mEventsCount);
        writer.println("    mEventsHistory=" + mEventsHistory);
    }


    private static void validateArguments(Handler handler, SensorManager sensorManager, int rate) {
        Preconditions.checkNotNull(handler, "handler cannot be null");
        Preconditions.checkNotNull(sensorManager, "sensorManager cannot be null");
        if (rate <= 0) {
            throw new IllegalArgumentException("rate must be positive");
        }
    }

    protected abstract void update(float value);

    private boolean enable() {
        if (mEnabled) {
            return false;
        }
        if (mLoggingEnabled) {
            Slog.d(mTag, "enabling");
        }
        mEnabled = true;
        startListening();
        return true;
    }

    private boolean disable() {
        if (!mEnabled) {
            return false;
        }
        if (mLoggingEnabled) {
            Slog.d(mTag, "disabling");
        }
        mEnabled = false;
        mEventsCount = 0;
        stopListening();
        return true;
    }

    private void startListening() {
        if (mSensorManager == null) {
            return;
        }
        mSensorManager.registerListener(mListener, mSensor, mRate * 1000, mHandler);
    }

    private void stopListening() {
        if (mSensorManager == null) {
            return;
        }
        mSensorManager.unregisterListener(mListener);
    }

    private void handleNewEvent(float value) {
        // This shouldn't really happen, except for the race condition where the sensor is disabled
        // with an event already in the handler queue, in which case we discard that event.
        if (!mEnabled) {
            return;
        }
        if (mLoggingEnabled) {
            Slog.d(mTag, "handle new event: " + value);
        }
        mEventsCount++;
        mEventsHistory.add(value);
        update(value);
    }

    private SensorEventListener mListener = new SensorEventListener() {

        @Override
        public void onSensorChanged(SensorEvent event) {
            final float value = event.values[0];
            handleNewEvent(value);
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            // Not used.
        }

    };

    /**
     * A sensor that reports the ambient brightness.
     */
    static class AmbientBrightnessSensor extends AmbientSensor {

        private static final String TAG = "AmbientBrightnessSensor";

        // To decouple the DisplayWhiteBalanceController from the AmbientBrightnessSensor, the
        // DWBC implements Callbacks and passes itself to the ABS so it can call back into it
        // without knowing about it.
        @Nullable
        private Callbacks mCallbacks;

        /**
         * @param handler
         *      The handler used to determine which thread to run on.
         * @param sensorManager
         *      The sensor manager used to acquire necessary sensors.
         * @param rate
         *      The sensor rate.
         *
         * @throws IllegalArgumentException
         *      - rate is not positive.
         * @throws NullPointerException
         *      - handler is null;
         *      - sensorManager is null.
         * @throws IllegalStateException
         *      - Cannot find the light sensor.
         */
        AmbientBrightnessSensor(@NonNull Handler handler, @NonNull SensorManager sensorManager,
                int rate) {
            super(TAG, handler, sensorManager, rate);
            mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
            if (mSensor == null) {
                throw new IllegalStateException("cannot find light sensor");
            }
            mCallbacks = null;
        }

        /**
         * Set an object to call back to when the ambient brightness changes.
         *
         * @param callbacks
         *      The object to call back to.
         *
         * @return Whether the method succeeded or not.
         */
        public boolean setCallbacks(Callbacks callbacks) {
            if (mCallbacks == callbacks) {
                return false;
            }
            mCallbacks = callbacks;
            return true;
        }

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

        interface Callbacks {
            void onAmbientBrightnessChanged(float value);
        }

        @Override
        protected void update(float value) {
            if (mCallbacks != null) {
                mCallbacks.onAmbientBrightnessChanged(value);
            }
        }

    }

    /**
     * A sensor that reports the ambient color temperature.
     */
    static class AmbientColorTemperatureSensor extends AmbientSensor {

        private static final String TAG = "AmbientColorTemperatureSensor";

        // To decouple the DisplayWhiteBalanceController from the
        // AmbientColorTemperatureSensor, the DWBC implements Callbacks and passes itself to the
        // ACTS so it can call back into it without knowing about it.
        @Nullable
        private Callbacks mCallbacks;

        /**
         * @param handler
         *      The handler used to determine which thread to run on.
         * @param sensorManager
         *      The sensor manager used to acquire necessary sensors.
         * @param name
         *      The color sensor name.
         * @param rate
         *      The sensor rate.
         *
         * @throws IllegalArgumentException
         *      - rate is not positive.
         * @throws NullPointerException
         *      - handler is null;
         *      - sensorManager is null.
         * @throws IllegalStateException
         *      - Cannot find the color sensor.
         */
        AmbientColorTemperatureSensor(@NonNull Handler handler,
                @NonNull SensorManager sensorManager, String name, int rate) {
            super(TAG, handler, sensorManager, rate);
            mSensor = null;
            for (Sensor sensor : mSensorManager.getSensorList(Sensor.TYPE_ALL)) {
                if (sensor.getStringType().equals(name)) {
                    mSensor = sensor;
                    break;
                }
            }
            if (mSensor == null) {
                throw new IllegalStateException("cannot find sensor " + name);
            }
            mCallbacks = null;
        }

        /**
         * Set an object to call back to when the ambient color temperature changes.
         *
         * @param callbacks
         *      The object to call back to.
         *
         * @return Whether the method succeeded or not.
         */
        public boolean setCallbacks(Callbacks callbacks) {
            if (mCallbacks == callbacks) {
                return false;
            }
            mCallbacks = callbacks;
            return true;
        }

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

        interface Callbacks {
            void onAmbientColorTemperatureChanged(float value);
        }

        @Override
        protected void update(float value) {
            if (mCallbacks != null) {
                mCallbacks.onAmbientColorTemperatureChanged(value);
            }
        }

    }

}
