/*
 * 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.text.method.ScrollingMovementMethod;
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);
        mSensorInfo.setMovementMethod(new ScrollingMovementMethod());
        mLocationInfo = (TextView) view.findViewById(R.id.location_info);
        mLocationInfo.setMovementMethod(new ScrollingMovementMethod());
        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);
            }
        }
    }
}
