/*
 * Copyright (c) 2016, 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.car.hvac;

import android.app.Service;
import android.car.VehicleAreaSeat;
import android.car.VehicleAreaWindow;
import android.car.hardware.CarPropertyConfig;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.hvac.CarHvacManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemProperties;
import android.support.car.Car;
import android.support.car.CarNotConnectedException;
import android.support.car.CarConnectionCallback;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.concurrent.GuardedBy;

public class HvacController extends Service {
    private static final String DEMO_MODE_PROPERTY = "android.car.hvac.demo";
    private static final String TAG = "HvacController";
    private static final int DRIVER_ZONE_ID = VehicleAreaSeat.SEAT_ROW_1_LEFT |
            VehicleAreaSeat.SEAT_ROW_2_LEFT | VehicleAreaSeat.SEAT_ROW_2_CENTER;
    private static final int PASSENGER_ZONE_ID = VehicleAreaSeat.SEAT_ROW_1_RIGHT |
            VehicleAreaSeat.SEAT_ROW_2_RIGHT;

    public static final int[] AIRFLOW_STATES = new int[]{
            CarHvacManager.FAN_DIRECTION_FACE,
            CarHvacManager.FAN_DIRECTION_FLOOR,
            (CarHvacManager.FAN_DIRECTION_FACE | CarHvacManager.FAN_DIRECTION_FLOOR)
    };
    // Hardware specific value for the front seats
    public static final int SEAT_ALL = VehicleAreaSeat.SEAT_ROW_1_LEFT |
            VehicleAreaSeat.SEAT_ROW_1_RIGHT | VehicleAreaSeat.SEAT_ROW_2_LEFT |
            VehicleAreaSeat.SEAT_ROW_2_CENTER | VehicleAreaSeat.SEAT_ROW_2_RIGHT;

    /**
     * Callback for receiving updates from the hvac manager. A Callback can be
     * registered using {@link #registerCallback}.
     */
    public static abstract class Callback {

        public void onPassengerTemperatureChange(CarPropertyValue propValue) {
        }

        public void onDriverTemperatureChange(CarPropertyValue propValue) {
        }

        public void onFanSpeedChange(int position) {
        }

        public void onAcStateChange(boolean isOn) {
        }

        public void onFrontDefrosterChange(boolean isOn) {
        }

        public void onRearDefrosterChange(boolean isOn) {
        }

        public void onPassengerSeatWarmerChange(int level) {
        }

        public void onDriverSeatWarmerChange(int level) {
        }

        public void onFanDirectionChange(int direction) {
        }

        public void onAirCirculationChange(boolean isOn) {
        }

        public void onAutoModeChange(boolean isOn) {
        }

        public void onHvacPowerChange(boolean isOn){
        }
    }

    public class LocalBinder extends Binder {
        HvacController getService() {
            return HvacController.this;
        }
    }

    private final Binder mBinder = new LocalBinder();

    private Car mCarApiClient;
    private CarHvacManager mHvacManager;
    private Object mHvacManagerReady = new Object();

    private HvacPolicy mPolicy;
    @GuardedBy("mCallbacks")
    private List<Callback> mCallbacks = new ArrayList<>();
    private DataStore mDataStore = new DataStore();

    @Override
    public void onCreate() {
        super.onCreate();
        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
            if (SystemProperties.getBoolean(DEMO_MODE_PROPERTY, false)) {
                IBinder binder = (new LocalHvacPropertyService()).getCarPropertyService();
                initHvacManager(new CarHvacManager(binder, this, new Handler()));
                return;
            }

            mCarApiClient = Car.createCar(this, mCarConnectionCallback);
            mCarApiClient.connect();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mHvacManager != null) {
            mHvacManager.unregisterCallback(mHardwareCallback);
        }
        if (mCarApiClient != null) {
            mCarApiClient.disconnect();
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    public void registerCallback(Callback callback) {
        synchronized (mCallbacks) {
            mCallbacks.add(callback);
        }
    }

    public void unregisterCallback(Callback callback) {
        synchronized (mCallbacks) {
            mCallbacks.remove(callback);
        }
    }

    private void initHvacManager(CarHvacManager carHvacManager) {
        mHvacManager = carHvacManager;
        List<CarPropertyConfig> properties = null;
        try {
            properties = mHvacManager.getPropertyList();
            mPolicy = new HvacPolicy(HvacController.this, properties);
            mHvacManager.registerCallback(mHardwareCallback);
        } catch (android.car.CarNotConnectedException e) {
            Log.e(TAG, "Car not connected in HVAC");
        }

    }

    private final CarConnectionCallback mCarConnectionCallback =
            new CarConnectionCallback() {
                @Override
                public void onConnected(Car car) {
                    synchronized (mHvacManagerReady) {
                        try {
                            initHvacManager((CarHvacManager) mCarApiClient.getCarManager(
                                    android.car.Car.HVAC_SERVICE));
                            mHvacManagerReady.notifyAll();
                        } catch (CarNotConnectedException e) {
                            Log.e(TAG, "Car not connected in onServiceConnected");
                        }
                    }
                }

                @Override
                public void onDisconnected(Car car) {
                }
            };

    private final CarHvacManager.CarHvacEventCallback mHardwareCallback =
            new CarHvacManager.CarHvacEventCallback() {
                @Override
                public void onChangeEvent(final CarPropertyValue val) {
                    int areaId = val.getAreaId();
                    switch (val.getPropertyId()) {
                        case CarHvacManager.ID_ZONED_AC_ON:
                            handleAcStateUpdate(getValue(val));
                            break;
                        case CarHvacManager.ID_ZONED_FAN_DIRECTION:
                            handleFanPositionUpdate(areaId, getValue(val));
                            break;
                        case CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT:
                            handleFanSpeedUpdate(areaId, getValue(val));
                            break;
                        case CarHvacManager.ID_ZONED_TEMP_SETPOINT:
                            handleTempUpdate(val);
                            break;
                        case CarHvacManager.ID_WINDOW_DEFROSTER_ON:
                            handleDefrosterUpdate(areaId, getValue(val));
                            break;
                        case CarHvacManager.ID_ZONED_AIR_RECIRCULATION_ON:
                            handleAirCirculationUpdate(getValue(val));
                            break;
                        case CarHvacManager.ID_ZONED_SEAT_TEMP:
                            handleSeatWarmerUpdate(areaId, getValue(val));
                            break;
                        case CarHvacManager.ID_ZONED_AUTOMATIC_MODE_ON:
                            handleAutoModeUpdate(getValue(val));
                            break;
                        case CarHvacManager.ID_ZONED_HVAC_POWER_ON:
                            handleHvacPowerOn(getValue(val));
                            break;
                        default:
                            if (Log.isLoggable(TAG, Log.DEBUG)) {
                                Log.d(TAG, "Unhandled HVAC event, id: " + val.getPropertyId());
                            }
                    }
                }

                @Override
                public void onErrorEvent(final int propertyId, final int zone) {
                }
            };

    @SuppressWarnings("unchecked")
    public static <E> E getValue(CarPropertyValue propertyValue) {
        return (E) propertyValue.getValue();
    }

    public static boolean isAvailable(CarPropertyValue propertyValue) {
        return propertyValue.getStatus() == CarPropertyValue.STATUS_AVAILABLE;
    }

    void handleHvacPowerOn(boolean isOn) {
        boolean shouldPropagate = mDataStore.shouldPropagateHvacPowerUpdate(isOn);
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Hvac Power On: " + isOn + " should propagate: " + shouldPropagate);
        }
        if (shouldPropagate) {
            synchronized (mCallbacks) {
                for (int i = 0; i < mCallbacks.size(); i++) {
                    mCallbacks.get(i).onHvacPowerChange(isOn);
                }
            }
        }
    }

    void handleSeatWarmerUpdate(int zone, int level) {
        boolean shouldPropagate = mDataStore.shouldPropagateSeatWarmerLevelUpdate(zone, level);
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Seat Warmer Update, zone: " + zone + " level: " + level +
                    " should propagate: " + shouldPropagate);
        }
        if (shouldPropagate) {
            synchronized (mCallbacks) {
                for (int i = 0; i < mCallbacks.size(); i++) {
                    if (zone == VehicleAreaSeat.SEAT_ROW_1_LEFT) {
                        mCallbacks.get(i).onDriverSeatWarmerChange(level);
                    } else {
                        mCallbacks.get(i).onPassengerSeatWarmerChange(level);
                    }
                }
            }
        }
    }

    private void handleAirCirculationUpdate(boolean airCirculationState) {
        boolean shouldPropagate
                = mDataStore.shouldPropagateAirCirculationUpdate(airCirculationState);
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Air Circulation Update: " + airCirculationState +
                    " should propagate: " + shouldPropagate);
        }
        if (shouldPropagate) {
            synchronized (mCallbacks) {
                for (int i = 0; i < mCallbacks.size(); i++) {
                    mCallbacks.get(i).onAirCirculationChange(airCirculationState);
                }
            }
        }
    }

    private void handleAutoModeUpdate(boolean autoModeState) {
        boolean shouldPropagate = mDataStore.shouldPropagateAutoModeUpdate(autoModeState);
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "AutoMode Update, id: " + autoModeState +
                    " should propagate: " + shouldPropagate);
        }
        if (shouldPropagate) {
            synchronized (mCallbacks) {
                for (int i = 0; i < mCallbacks.size(); i++) {
                    mCallbacks.get(i).onAutoModeChange(autoModeState);
                }
            }
        }
    }

    private void handleAcStateUpdate(boolean acState) {
        boolean shouldPropagate = mDataStore.shouldPropagateAcUpdate(acState);
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "AC State Update, id: " + acState +
                    " should propagate: " + shouldPropagate);
        }
        if (shouldPropagate) {
            synchronized (mCallbacks) {
                for (int i = 0; i < mCallbacks.size(); i++) {
                    mCallbacks.get(i).onAcStateChange(acState);
                }
            }
        }
    }

    private void handleFanPositionUpdate(int zone, int position) {
        int index = fanPositionToAirflowIndex(position);
        boolean shouldPropagate = mDataStore.shouldPropagateFanPositionUpdate(zone, index);
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Fan Position Update, zone: " + zone + " position: " + position +
                    " should propagate: " + shouldPropagate);
        }
        if (shouldPropagate) {
            synchronized (mCallbacks) {
                for (int i = 0; i < mCallbacks.size(); i++) {
                    mCallbacks.get(i).onFanDirectionChange(position);
                }
            }
        }
    }

    private void handleFanSpeedUpdate(int zone, int speed) {
        boolean shouldPropagate = mDataStore.shouldPropagateFanSpeedUpdate(zone, speed);
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Fan Speed Update, zone: " + zone + " speed: " + speed +
                    " should propagate: " + shouldPropagate);
        }
        if (shouldPropagate) {
            synchronized (mCallbacks) {
                for (int i = 0; i < mCallbacks.size(); i++) {
                    mCallbacks.get(i).onFanSpeedChange(speed);
                }
            }
        }
    }

    private void handleTempUpdate(CarPropertyValue value) {
        final int zone = value.getAreaId();
        final float temp = (Float)value.getValue();
        final boolean available = value.getStatus() == CarPropertyValue.STATUS_AVAILABLE;
        boolean shouldPropagate = mDataStore.shouldPropagateTempUpdate(zone, temp, available);
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Temp Update, zone: " + zone + " temp: " + temp +
                "available: " + available + " should propagate: " + shouldPropagate);
        }
        if (shouldPropagate) {
            int userTemperature =  mPolicy.hardwareToUserTemp(temp);
            synchronized (mCallbacks) {
                for (int i = 0; i < mCallbacks.size(); i++) {
                    if (zone == VehicleAreaSeat.SEAT_ROW_1_LEFT) {
                        mCallbacks.get(i)
                                .onDriverTemperatureChange(value);
                    } else {
                        mCallbacks.get(i)
                                .onPassengerTemperatureChange(value);
                    }
                }
            }
        }
    }

    private void handleDefrosterUpdate(int zone, boolean defrosterState) {
        boolean shouldPropagate = mDataStore.shouldPropagateDefrosterUpdate(zone, defrosterState);
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Defroster Update, zone: " + zone + " state: " + defrosterState +
                    " should propagate: " + shouldPropagate);
        }
        if (shouldPropagate) {
            synchronized (mCallbacks) {
                for (int i = 0; i < mCallbacks.size(); i++) {
                    if (zone == VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD) {
                        mCallbacks.get(i).onFrontDefrosterChange(defrosterState);
                    } else if (zone == VehicleAreaWindow.WINDOW_REAR_WINDSHIELD) {
                        mCallbacks.get(i).onRearDefrosterChange(defrosterState);
                    }
                }
            }
        }
    }

    public void requestRefresh(final Runnable r, final Handler h) {
        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... unused) {
                synchronized (mHvacManagerReady) {
                    while (mHvacManager == null) {
                        try {
                            mHvacManagerReady.wait();
                        } catch (InterruptedException e) {
                            // We got interrupted so we might be shutting down.
                            return null;
                        }
                    }
                }
                fetchTemperature(DRIVER_ZONE_ID);
                fetchTemperature(PASSENGER_ZONE_ID);
                fetchFanSpeed();
                fetchDefrosterState(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD);
                fetchDefrosterState(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD);
                fetchAirflow(DRIVER_ZONE_ID);
                fetchAirflow(PASSENGER_ZONE_ID);
                fetchAcState();
                fetchAirCirculation();
                fetchHvacPowerState();
                return null;
            }

            @Override
            protected void onPostExecute(Void unused) {
                h.post(r);
            }
        };
        task.execute();
    }

    public HvacPolicy getPolicy() {
        return mPolicy;
    }

    public boolean isTemperatureControlAvailable(int zone) {
        if (mHvacManager != null) {
            try {
                return mHvacManager.isPropertyAvailable(
                        CarHvacManager.ID_ZONED_TEMP_SETPOINT, zone);
            } catch (android.car.CarNotConnectedException e) {
                Log.e(TAG, "Car not connected in isTemperatureControlAvailable");
            }
        }

        return false;
    }

    public boolean isDriverTemperatureControlAvailable() {
        return isTemperatureControlAvailable(DRIVER_ZONE_ID);
    }

    public boolean isPassengerTemperatureControlAvailable() {
        return isTemperatureControlAvailable(PASSENGER_ZONE_ID);
    }

    private void fetchTemperature(int zone) {
        if (mHvacManager != null) {
            try {
                float value = mHvacManager.getFloatProperty(
                    CarHvacManager.ID_ZONED_TEMP_SETPOINT, zone);
                boolean available = mHvacManager.isPropertyAvailable(
                    CarHvacManager.ID_ZONED_TEMP_SETPOINT, zone);
                mDataStore.setTemperature(zone, value, available);
            } catch (android.car.CarNotConnectedException e) {
                Log.e(TAG, "Car not connected in fetchTemperature");
            }
        }
    }

    public int getDriverTemperature() {
        return mPolicy.hardwareToUserTemp(mDataStore.getTemperature(DRIVER_ZONE_ID));
    }

    public int getPassengerTemperature() {
        return mPolicy.hardwareToUserTemp(mDataStore.getTemperature(PASSENGER_ZONE_ID));
    }

    public void setDriverTemperature(int temperature) {
        setTemperature(DRIVER_ZONE_ID, mPolicy.userToHardwareTemp(temperature));
    }

    public void setPassengerTemperature(int temperature) {
        setTemperature(PASSENGER_ZONE_ID, mPolicy.userToHardwareTemp(temperature));
    }

    public void setTemperature(final int zone, final float temperature) {
        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            protected Void doInBackground(Void... unused) {
                if (mHvacManager != null) {
                    try {
                        mHvacManager.setFloatProperty(
                                CarHvacManager.ID_ZONED_TEMP_SETPOINT, zone, temperature);
                        // if the set() succeeds, consider the property available
                        mDataStore.setTemperature(zone, temperature, true);
                    } catch (android.car.CarNotConnectedException e) {
                        Log.e(TAG, "Car not connected in setTemperature");
                    } catch (Exception e) {
                        Log.e(TAG, "set temp failed", e);
                    }
                }
                return null;
            }
        };
        task.execute();
    }

    public void setHvacPowerState(final boolean state) {
        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            protected Void doInBackground(Void... unused) {
                if (mHvacManager != null) {
                    try {
                        mHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_HVAC_POWER_ON,
                            SEAT_ALL, state);
                        // if the set() succeeds, consider the property available
                        mDataStore.setHvacPowerState(state);
                    } catch (android.car.CarNotConnectedException e) {
                        Log.e(TAG, "Car not connected in setHvacPowerState");
                    } catch (Exception e) {
                        Log.e(TAG, "set power failed", e);
                    }
                }
                return null;
            }
        };
        task.execute();
    }

    public void setDriverSeatWarmerLevel(int level) {
        setSeatWarmerLevel(DRIVER_ZONE_ID, level);
    }

    public void setPassengerSeatWarmerLevel(int level) {
        setSeatWarmerLevel(PASSENGER_ZONE_ID, level);
    }

    public void setSeatWarmerLevel(final int zone, final int level) {
        mDataStore.setSeatWarmerLevel(zone, level);
        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            protected Void doInBackground(Void... unused) {
                if (mHvacManager != null) {
                    try {
                        mHvacManager.setIntProperty(
                                CarHvacManager.ID_ZONED_SEAT_TEMP, zone, level);
                    } catch (android.car.CarNotConnectedException e) {
                        Log.e(TAG, "Car not connected in setSeatWarmerLevel");
                    } catch (Exception e) {
                        Log.e(TAG, "set seat warmer failed", e);
                    }
                }
                return null;
            }
        };
        task.execute();
    }

    private void fetchFanSpeed() {
        if (mHvacManager != null) {
            int zone = SEAT_ALL; // Car specific workaround.
            try {
                mDataStore.setFanSpeed(mHvacManager.getIntProperty(
                        CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT, zone));
            } catch (android.car.CarNotConnectedException e) {
                Log.e(TAG, "Car not connected in fetchFanSpeed");
            }
        }
    }

    public int getFanSpeed() {
        return mDataStore.getFanSpeed();
    }

    public void setFanSpeed(final int fanSpeed) {
        mDataStore.setFanSpeed(fanSpeed);

        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            int newFanSpeed;

            protected Void doInBackground(Void... unused) {
                if (mHvacManager != null) {
                    int zone = SEAT_ALL; // Car specific workaround.
                    try {
                        if (Log.isLoggable(TAG, Log.DEBUG)) {
                            Log.d(TAG, "Setting fanspeed to: " + fanSpeed);
                        }
                        mHvacManager.setIntProperty(
                                CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT, zone, fanSpeed);

                        newFanSpeed = mHvacManager.getIntProperty(
                                CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT, zone);
                    } catch (android.car.CarNotConnectedException e) {
                        Log.e(TAG, "Car not connected in setFanSpeed");
                    }
                }
                return null;
            }

            @Override
            protected void onPostExecute(final Void result) {
                Log.e(TAG, "postExecute new fanSpeed: " + newFanSpeed);
            }
        };
        task.execute();
    }

    private void fetchDefrosterState(int zone) {
        if (mHvacManager != null) {
            try {
                mDataStore.setDefrosterState(zone, mHvacManager.getBooleanProperty(
                        CarHvacManager.ID_WINDOW_DEFROSTER_ON, zone));
            } catch (android.car.CarNotConnectedException e) {
                Log.e(TAG, "Car not connected in fetchDefrosterState");
            }
        }
    }

    public boolean getFrontDefrosterState() {
        return mDataStore.getDefrosterState(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD);
    }

    public boolean getRearDefrosterState() {
        return mDataStore.getDefrosterState(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD);
    }

    public void setFrontDefrosterState(boolean state) {
        setDefrosterState(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD, state);
    }

    public void setRearDefrosterState(boolean state) {
        setDefrosterState(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, state);
    }

    public void setDefrosterState(final int zone, final boolean state) {
        mDataStore.setDefrosterState(zone, state);
        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            protected Void doInBackground(Void... unused) {
                if (mHvacManager != null) {
                    try {
                        mHvacManager.setBooleanProperty(
                                CarHvacManager.ID_WINDOW_DEFROSTER_ON, zone, state);
                    } catch (android.car.CarNotConnectedException e) {
                        Log.e(TAG, "Car not connected in setDeforsterState");
                    }
                }
                return null;
            }
        };
        task.execute();
    }

    private void fetchAcState() {
        if (mHvacManager != null) {
            try {
                mDataStore.setAcState(mHvacManager.getBooleanProperty(CarHvacManager.ID_ZONED_AC_ON,
                        SEAT_ALL));
            } catch (android.car.CarNotConnectedException e) {
                Log.e(TAG, "Car not connected in fetchAcState");
            }
        }
    }

    public boolean getAcState() {
        return mDataStore.getAcState();
    }

    public void setAcState(final boolean state) {
        mDataStore.setAcState(state);
        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            protected Void doInBackground(Void... unused) {
                if (mHvacManager != null) {
                    try {
                        mHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_AC_ON,
                                SEAT_ALL, state);
                    } catch (android.car.CarNotConnectedException e) {
                        Log.e(TAG, "Car not connected in setAcState");
                    }
                }
                return null;
            }
        };
        task.execute();
    }

    private int fanPositionToAirflowIndex(int fanPosition) {
        for (int i = 0; i < AIRFLOW_STATES.length; i++) {
            if (fanPosition == AIRFLOW_STATES[i]) {
                return i;
            }
        }
        Log.e(TAG, "Unknown fan position " + fanPosition + ". Returning default.");
        return AIRFLOW_STATES[0];
    }

    private void fetchAirflow(int zone) {
        if (mHvacManager != null) {
            zone = SEAT_ALL; // Car specific workaround.
            try {
                int val = mHvacManager.getIntProperty(CarHvacManager.ID_ZONED_FAN_DIRECTION, zone);
                mDataStore.setAirflow(zone, fanPositionToAirflowIndex(val));
            } catch (android.car.CarNotConnectedException e) {
                Log.e(TAG, "Car not connected in fetchAirFlow");
            }
        }
    }

    public int getAirflowIndex(int zone) {
        return mDataStore.getAirflow(zone);
    }

    public void setAirflowIndex(final int zone, final int index) {
        mDataStore.setAirflow(zone, index);
        int override = SEAT_ALL; // Car specific workaround.
        int val = AIRFLOW_STATES[index];
        setFanDirection(override, val);
    }

    public void setFanDirection(final int direction) {
        mDataStore.setAirflow(SEAT_ALL, direction);
        setFanDirection(SEAT_ALL, direction);
    }

    private void setFanDirection(final int zone, final int direction) {
        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            protected Void doInBackground(Void... unused) {
                if (mHvacManager != null) {
                    try {
                        mHvacManager.setIntProperty(
                                CarHvacManager.ID_ZONED_FAN_DIRECTION, zone, direction);
                    } catch (android.car.CarNotConnectedException e) {
                        Log.e(TAG, "Car not connected in setAirflowIndex");
                    }
                }
                return null;
            }
        };
        task.execute();
    }


    private void fetchAirCirculation() {
        if (mHvacManager != null) {
            try {
                mDataStore.setAirCirculationState(mHvacManager
                        .getBooleanProperty(CarHvacManager.ID_ZONED_AIR_RECIRCULATION_ON,
                                SEAT_ALL));
            } catch (android.car.CarNotConnectedException e) {
                Log.e(TAG, "Car not connected in fetchAirCirculationState");
            }
        }
    }

    public boolean getAirCirculationState() {
        return mDataStore.getAirCirculationState();
    }

    public void setAirCirculation(final boolean state) {
        mDataStore.setAirCirculationState(state);
        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            protected Void doInBackground(Void... unused) {
                if (mHvacManager != null) {
                    try {
                        mHvacManager.setBooleanProperty(
                                CarHvacManager.ID_ZONED_AIR_RECIRCULATION_ON,
                                SEAT_ALL, state);
                    } catch (android.car.CarNotConnectedException e) {
                        Log.e(TAG, "Car not connected in setAcState");
                    }
                }
                return null;
            }
        };
        task.execute();
    }

    public boolean getAutoModeState() {
        return mDataStore.getAutoModeState();
    }

    public void setAutoMode(final boolean state) {
        mDataStore.setAutoModeState(state);
        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            protected Void doInBackground(Void... unused) {
                if (mHvacManager != null) {
                    try {
                        mHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_AUTOMATIC_MODE_ON,
                                SEAT_ALL, state);
                    } catch (android.car.CarNotConnectedException e) {
                        Log.e(TAG, "Car not connected in setAutoModeState");
                    }
                }
                return null;
            }
        };
        task.execute();
    }

    public boolean getHvacPowerState() {
        return mDataStore.getHvacPowerState();
    }

    private void fetchHvacPowerState() {
        if (mHvacManager != null) {
            try {
                mDataStore.setHvacPowerState(mHvacManager.getBooleanProperty(
                        CarHvacManager.ID_ZONED_HVAC_POWER_ON, SEAT_ALL));
            } catch (android.car.CarNotConnectedException e) {
                Log.e(TAG, "Car not connected in fetchHvacPowerState");
            }
        }
    }
}
