/*
 * 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.google.android.car.kitchensink.sensor;

import static java.lang.Integer.toHexString;

import android.Manifest;
import android.annotation.Nullable;
import android.car.Car;
import android.car.hardware.CarSensorConfig;
import android.car.hardware.CarSensorEvent;
import android.car.hardware.CarSensorManager;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.fragment.app.Fragment;

import com.google.android.car.kitchensink.KitchenSinkActivity;
import com.google.android.car.kitchensink.R;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class SensorsTestFragment extends Fragment {
    private static final String TAG = "CAR.SENSOR.KS";
    private static final boolean DBG = true;
    private static final boolean DBG_VERBOSE = true;
    private static final int KS_PERMISSIONS_REQUEST = 1;

    private final static String[] REQUIRED_PERMISSIONS = new String[]{
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Car.PERMISSION_MILEAGE,
        Car.PERMISSION_ENERGY,
        Car.PERMISSION_SPEED,
        Car.PERMISSION_CAR_DYNAMICS_STATE
    };

    private final CarSensorManager.OnSensorChangedListener mOnSensorChangedListener =
            new CarSensorManager.OnSensorChangedListener() {
                @Override
                public void onSensorChanged(CarSensorEvent event) {
                    if (DBG_VERBOSE) {
                        Log.v(TAG, "New car sensor event: " + event);
                    }
                    synchronized (SensorsTestFragment.this) {
                        mEventMap.put(event.sensorType, event);
                    }
                    refreshSensorInfoText();
                }
            };
    private final Handler mHandler = new Handler();
    private final Map<Integer, CarSensorEvent> mEventMap = new ConcurrentHashMap<>();
    private final DateFormat mDateFormat = SimpleDateFormat.getDateTimeInstance();

    private KitchenSinkActivity mActivity;
    private Car mCar;
    private CarSensorManager mCarSensorManager;
    private LocationListeners mLocationListener;
    private String mNaString;
    private int[] supportedSensors = new int[0];
    private Set<String> mActivePermissions = new HashSet<String>();

    private TextView mSensorInfo;
    private TextView mLocationInfo;
    private TextView mAccelInfo;
    private TextView mGyroInfo;
    private TextView mMagInfo;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        if (DBG) {
            Log.i(TAG, "onCreateView");
        }

        View view = inflater.inflate(R.layout.sensors, container, false);
        mActivity = (KitchenSinkActivity) getHost();

        mSensorInfo = (TextView) view.findViewById(R.id.sensor_info);
        mLocationInfo = (TextView) view.findViewById(R.id.location_info);
        mAccelInfo = (TextView) view.findViewById(R.id.accel_info);
        mGyroInfo = (TextView) view.findViewById(R.id.gyro_info);
        mMagInfo = (TextView) view.findViewById(R.id.mag_info);

        mNaString = getContext().getString(R.string.sensor_na);
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        final Runnable r = () -> {
            initPermissions();
        };
        ((KitchenSinkActivity) getActivity()).requestRefreshManager(r,
                new Handler(getContext().getMainLooper()));
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mCarSensorManager != null) {
            mCarSensorManager.unregisterListener(mOnSensorChangedListener);
        }
        if (mLocationListener != null) {
            mLocationListener.stopListening();
        }
    }

    private void initSensors() {
        try {
            if (mCarSensorManager == null) {
                mCarSensorManager =
                    (CarSensorManager) ((KitchenSinkActivity) getActivity()).getSensorManager();
            }
            supportedSensors = mCarSensorManager.getSupportedSensors();
            for (Integer sensor : supportedSensors) {
                mCarSensorManager.registerListener(mOnSensorChangedListener, sensor,
                        CarSensorManager.SENSOR_RATE_NORMAL);
            }
        } catch (Exception e) {
            Log.e(TAG, "initSensors() exception caught SensorManager: ", e);
        }
        try {
            if (mLocationListener == null) {
                mLocationListener = new LocationListeners(getContext(),
                                                          new LocationInfoTextUpdateListener());
            }
            mLocationListener.startListening();
        } catch (Exception e) {
            Log.e(TAG, "initSensors() exception caught from LocationListeners: ", e);
        }
    }

    private void initPermissions() {
        Set<String> missingPermissions = checkExistingPermissions();
        if (!missingPermissions.isEmpty()) {
            requestPermissions(missingPermissions);
            // The callback with premission results will take care of calling initSensors for us
        } else {
            initSensors();
        }
    }

    private Set<String> checkExistingPermissions() {
        Set<String> missingPermissions = new HashSet<String>();
        for (String permission : REQUIRED_PERMISSIONS) {
            if (mActivity.checkSelfPermission(permission)
                == PackageManager.PERMISSION_GRANTED) {
                mActivePermissions.add(permission);
            } else {
                missingPermissions.add(permission);
            }
        }
        return missingPermissions;
    }

    private void requestPermissions(Set<String> permissions) {
        Log.d(TAG, "requesting additional permissions=" + permissions);

        requestPermissions(permissions.toArray(new String[permissions.size()]),
                KS_PERMISSIONS_REQUEST);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
            int[] grantResults) {
        Log.d(TAG, "onRequestPermissionsResult reqCode=" + requestCode);
        if (KS_PERMISSIONS_REQUEST == requestCode) {
            for (int i=0; i<permissions.length; i++) {
                if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                    mActivePermissions.add(permissions[i]);
                }
            }
            initSensors();
        }
    }

    private void refreshSensorInfoText() {
        String summaryString;
        synchronized (this) {
            List<String> summary = new ArrayList<>();
            for (Integer i : supportedSensors) {
                CarSensorEvent event = mEventMap.get(i);
                switch (i) {
                    case CarSensorManager.SENSOR_TYPE_CAR_SPEED:
                        summary.add(getContext().getString(R.string.sensor_speed,
                                getTimestamp(event),
                                event == null ? mNaString : event.getCarSpeedData(null).carSpeed));
                        break;
                    case CarSensorManager.SENSOR_TYPE_RPM:
                        summary.add(getContext().getString(R.string.sensor_rpm,
                                getTimestamp(event),
                                event == null ? mNaString : event.getRpmData(null).rpm));
                        break;
                    case CarSensorManager.SENSOR_TYPE_ODOMETER:
                        summary.add(getContext().getString(R.string.sensor_odometer,
                                getTimestamp(event),
                                event == null ? mNaString : event.getOdometerData(null).kms));
                        break;
                    case CarSensorManager.SENSOR_TYPE_FUEL_LEVEL:
                        summary.add(getFuelLevel(event));
                        break;
                    case CarSensorManager.SENSOR_TYPE_FUEL_DOOR_OPEN:
                        summary.add(getFuelDoorOpen(event));
                        break;
                    case CarSensorManager.SENSOR_TYPE_IGNITION_STATE:
                        summary.add(getContext().getString(R.string.sensor_ignition_status,
                                getTimestamp(event),
                                event == null ? mNaString :
                                event.getIgnitionStateData(null).ignitionState));
                        break;
                    case CarSensorManager.SENSOR_TYPE_PARKING_BRAKE:
                        summary.add(getContext().getString(R.string.sensor_parking_brake,
                                getTimestamp(event),
                                event == null ? mNaString :
                                event.getParkingBrakeData(null).isEngaged));
                        break;
                    case CarSensorManager.SENSOR_TYPE_GEAR:
                        summary.add(getContext().getString(R.string.sensor_gear,
                                getTimestamp(event),
                                event == null ? mNaString : event.getGearData(null).gear));
                        break;
                    case CarSensorManager.SENSOR_TYPE_NIGHT:
                        summary.add(getContext().getString(R.string.sensor_night,
                                getTimestamp(event),
                                event == null ? mNaString : event.getNightData(null).isNightMode));
                        break;
                    case CarSensorManager.SENSOR_TYPE_ENV_OUTSIDE_TEMPERATURE:
                        String temperature = mNaString;
                        if (event != null) {
                            CarSensorEvent.EnvironmentData env = event.getEnvironmentData(null);
                            temperature = Float.isNaN(env.temperature) ? temperature :
                                    String.valueOf(env.temperature);
                        }
                        summary.add(getContext().getString(R.string.sensor_environment,
                                getTimestamp(event), temperature));
                        break;
                    case CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE:
                        if(event != null) {
                            CarSensorEvent.CarWheelTickDistanceData d =
                                    event.getCarWheelTickDistanceData(null);
                            summary.add(getContext().getString(R.string.sensor_wheel_ticks,
                                getTimestamp(event), d.sensorResetCount, d.frontLeftWheelDistanceMm,
                                d.frontRightWheelDistanceMm, d.rearLeftWheelDistanceMm,
                                d.rearRightWheelDistanceMm));
                        } else {
                            summary.add(getContext().getString(R.string.sensor_wheel_ticks,
                                getTimestamp(event), mNaString, mNaString, mNaString, mNaString,
                                mNaString));
                        }
                        // Get the config data
                        CarSensorConfig c = mCarSensorManager.getSensorConfig(
                                CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE);
                        summary.add(getContext().getString(R.string.sensor_wheel_ticks_cfg,
                                c.getInt(CarSensorConfig.WHEEL_TICK_DISTANCE_SUPPORTED_WHEELS),
                                c.getInt(CarSensorConfig.WHEEL_TICK_DISTANCE_FRONT_LEFT_UM_PER_TICK),
                                c.getInt(CarSensorConfig.WHEEL_TICK_DISTANCE_FRONT_RIGHT_UM_PER_TICK),
                                c.getInt(CarSensorConfig.WHEEL_TICK_DISTANCE_REAR_LEFT_UM_PER_TICK),
                                c.getInt(CarSensorConfig.WHEEL_TICK_DISTANCE_REAR_RIGHT_UM_PER_TICK)));
                        break;
                    case CarSensorManager.SENSOR_TYPE_ABS_ACTIVE:
                        summary.add(getContext().getString(R.string.sensor_abs_is_active,
                            getTimestamp(event), event == null ? mNaString :
                                    event.getCarAbsActiveData(null).absIsActive));
                        break;

                    case CarSensorManager.SENSOR_TYPE_TRACTION_CONTROL_ACTIVE:
                        summary.add(
                            getContext().getString(R.string.sensor_traction_control_is_active,
                            getTimestamp(event), event == null ? mNaString :
                                    event.getCarTractionControlActiveData(null)
                                    .tractionControlIsActive));
                        break;
                    case CarSensorManager.SENSOR_TYPE_EV_BATTERY_LEVEL:
                        summary.add(getEvBatteryLevel(event));
                        break;
                    case CarSensorManager.SENSOR_TYPE_EV_CHARGE_PORT_OPEN:
                        summary.add(getEvChargePortOpen(event));
                        break;
                    case CarSensorManager.SENSOR_TYPE_EV_CHARGE_PORT_CONNECTED:
                        summary.add(getEvChargePortConnected(event));
                        break;
                    case CarSensorManager.SENSOR_TYPE_EV_BATTERY_CHARGE_RATE:
                        summary.add(getEvChargeRate(event));
                        break;
                    case CarSensorManager.SENSOR_TYPE_ENGINE_OIL_LEVEL:
                        summary.add(getEngineOilLevel(event));
                        break;
                    default:
                        // Should never happen.
                        Log.w(TAG, "Unrecognized event type: " + toHexString(i));
                }
            }
            summaryString = TextUtils.join("\n", summary);
        }
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mSensorInfo.setText(summaryString);
            }
        });
    }

    private String getTimestamp(CarSensorEvent event) {
        if (event == null) {
            return mNaString;
        }
        return Double.toString(event.timestamp / (1000L * 1000L * 1000L)) + " seconds";
    }

    private String getTimestampNow() {
        return Double.toString(System.nanoTime() / (1000L * 1000L * 1000L)) + " seconds";
    }

    private String getFuelLevel(CarSensorEvent event) {
        String fuelLevel = mNaString;
        if(event != null) {
            fuelLevel = String.valueOf(event.getFuelLevelData(null).level);
        }
        return getContext().getString(R.string.sensor_fuel_level, getTimestamp(event), fuelLevel);
    }

    private String getFuelDoorOpen(CarSensorEvent event) {
        String fuelDoorOpen = mNaString;
        if(event != null) {
            fuelDoorOpen = String.valueOf(event.getCarFuelDoorOpenData(null).fuelDoorIsOpen);
        }
        return getContext().getString(R.string.sensor_fuel_door_open, getTimestamp(event),
            fuelDoorOpen);
    }

    private String getEvBatteryLevel(CarSensorEvent event) {
        String evBatteryLevel = mNaString;
        if(event != null) {
            evBatteryLevel = String.valueOf(event.getCarEvBatteryLevelData(null).evBatteryLevel);
        }
        return getContext().getString(R.string.sensor_ev_battery_level, getTimestamp(event),
            evBatteryLevel);
    }

    private String getEvChargePortOpen(CarSensorEvent event) {
        String evChargePortOpen = mNaString;
        if(event != null) {
            evChargePortOpen = String.valueOf(
                event.getCarEvChargePortOpenData(null).evChargePortIsOpen);
        }
        return getContext().getString(R.string.sensor_ev_charge_port_is_open, getTimestamp(event),
            evChargePortOpen);
    }

    private String getEvChargePortConnected(CarSensorEvent event) {
        String evChargePortConnected = mNaString;
        if(event != null) {
            evChargePortConnected = String.valueOf(
                event.getCarEvChargePortConnectedData(null).evChargePortIsConnected);
        }
        return getContext().getString(R.string.sensor_ev_charge_port_is_connected,
            getTimestamp(event), evChargePortConnected);
    }

    private String getEvChargeRate(CarSensorEvent event) {
        String evChargeRate = mNaString;
        if(event != null) {
            evChargeRate = String.valueOf(event.getCarEvBatteryChargeRateData(null).evChargeRate);
        }
        return getContext().getString(R.string.sensor_ev_charge_rate, getTimestamp(event),
            evChargeRate);
    }

    private String getEngineOilLevel(CarSensorEvent event) {
        String engineOilLevel = mNaString;
        if(event != null) {
            engineOilLevel = String.valueOf(event.getCarEngineOilLevelData(null).engineOilLevel);
        }
        return  getContext().getString(R.string.sensor_oil_level, getTimestamp(event),
           engineOilLevel);
    }

    public class LocationInfoTextUpdateListener {
        public void setLocationField(String value) {
            setTimestampedTextField(mLocationInfo, value);
        }

        public void setAccelField(String value) {
            setTimestampedTextField(mAccelInfo, value);
        }

        public void setGyroField(String value) {
            setTimestampedTextField(mGyroInfo, value);
        }

        public void setMagField(String value) {
            setTimestampedTextField(mMagInfo, value);
        }

        private void setTimestampedTextField(TextView text, String value) {
            synchronized (SensorsTestFragment.this) {
                text.setText(getTimestampNow() + ": " + value);
                Log.d(TAG, "setText: " + value);
            }
        }
    }
}
