/*
 * 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.input;

import static android.hardware.automotive.vehicle.V2_0.SubscribeFlags.EVENTS_FROM_ANDROID;
import static android.hardware.automotive.vehicle.V2_0.SubscribeFlags.EVENTS_FROM_CAR;
import static android.hardware.automotive.vehicle.V2_0.VehicleDisplay.INSTRUMENT_CLUSTER;
import static android.hardware.automotive.vehicle.V2_0.VehicleHwKeyInputAction.ACTION_DOWN;
import static android.hardware.automotive.vehicle.V2_0.VehicleProperty.HW_KEY_INPUT;

import android.annotation.Nullable;
import android.annotation.StringRes;
import android.hardware.automotive.vehicle.V2_0.IVehicle;
import android.hardware.automotive.vehicle.V2_0.IVehicleCallback;
import android.hardware.automotive.vehicle.V2_0.IVehicleCallback.Stub;
import android.hardware.automotive.vehicle.V2_0.SubscribeOptions;
import android.hardware.automotive.vehicle.V2_0.VehicleArea;
import android.hardware.automotive.vehicle.V2_0.VehicleDisplay;
import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
import android.hardware.automotive.vehicle.V2_0.VehiclePropertyGroup;
import android.hardware.automotive.vehicle.V2_0.VehiclePropertyStatus;
import android.hardware.automotive.vehicle.V2_0.VehiclePropertyType;
import android.os.Bundle;
import android.os.RemoteException;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.fragment.app.Fragment;

import com.android.car.keventreader.EventReaderService;
import com.android.car.keventreader.IEventCallback;
import com.android.car.keventreader.KeypressEvent;

import com.google.android.car.kitchensink.R;
import com.google.android.collect.Lists;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;

/**
 * Test input event handling to system.
 * vehicle hal should have VEHICLE_PROPERTY_HW_KEY_INPUT support for this to work.
 */
public class InputTestFragment extends Fragment {

    private static final String TAG = "CAR.INPUT.KS";

    private static final Button BREAK_LINE = null;

    private final List<View> mButtons = new ArrayList<>();

    // This is fake data generation property available only in emulated VHAL implementation.
    private static final int sGenerateFakeDataControllingProperty =
            0x0666 | VehiclePropertyGroup.VENDOR | VehicleArea.GLOBAL | VehiclePropertyType.MIXED;
    // The key press command is sent with the fake data generation property. It's matching the
    // command defined in the emulated VHAL implementation.
    private static final int sKeyPressCommand = 100;

    private IVehicle mVehicle;

    private EventReaderService mEventReaderService;

    private final IEventCallback.Stub mKeypressEventHandler = new IEventCallback.Stub() {
        private String prettyPrint(KeypressEvent event) {
            return String.format("Event{source = %s, keycode = %s, key%s}\n",
                event.source,
                event.keycodeToString(),
                event.isKeydown ? "down" : "up");
        }

        @Override
        public void onEvent(KeypressEvent keypressEvent) throws RemoteException {
            Log.d(TAG, "received event " + keypressEvent);
            synchronized (mInputEventsList) {
                mInputEventsList.append(prettyPrint(keypressEvent));
            }
        }
    };

    private final IVehicleCallback.Stub mHalKeyEventHandler = new Stub() {
        private String prettyPrint(VehiclePropValue event) {
            if (event.prop != HW_KEY_INPUT) return "";
            if (event.value == null ||
                event.value.int32Values == null ||
                event.value.int32Values.size() < 2) return "";
            return String.format("Event{source = HAL, keycode = %s, key%s}\n",
                event.value.int32Values.get(1),
                event.value.int32Values.get(0) == ACTION_DOWN ? "down" : "up");
        }

        @Override
        public void onPropertyEvent(ArrayList<VehiclePropValue> propValues) throws RemoteException {
            synchronized (mInputEventsList) {
                propValues.forEach(vpv -> mInputEventsList.append(prettyPrint(vpv)));
            }
        }

        @Override
        public void onPropertySet(VehiclePropValue propValue) {}

        @Override
        public void onPropertySetError(int errorCode, int propId, int areaId) {}
    };

    private TextView mInputEventsList;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            mVehicle = IVehicle.getService();
        } catch (NoSuchElementException ex) {
            throw new RuntimeException("Couldn't connect to " + IVehicle.kInterfaceName, ex);
        } catch (RemoteException e) {
            throw new RuntimeException("Failed to connect to IVehicle");
        }
        Log.d(TAG, "Connected to IVehicle service: " + mVehicle);

        mEventReaderService = EventReaderService.tryGet();
        Log.d(TAG, "Key Event Reader service: " + mEventReaderService);
        if (mEventReaderService != null) {
            mEventReaderService.registerCallback(mKeypressEventHandler);
        }

        SubscribeOptions subscribeOption = new SubscribeOptions();
        subscribeOption.propId = HW_KEY_INPUT;
        subscribeOption.flags = EVENTS_FROM_CAR | EVENTS_FROM_ANDROID;
        ArrayList<SubscribeOptions> subscribeOptions = new ArrayList<>();
        subscribeOptions.add(subscribeOption);
        try {
            mVehicle.subscribe(mHalKeyEventHandler, subscribeOptions);
        } catch (RemoteException e) {
            Log.e(TAG, "failed to connect to VHAL for key events", e);
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.input_test, container, false);

        mInputEventsList = view.findViewById(R.id.events_list);
        mInputEventsList.setMovementMethod(new ScrollingMovementMethod());

        TextView steeringWheelLabel = new TextView(getActivity() /*context*/);
        steeringWheelLabel.setText(R.string.steering_wheel);
        steeringWheelLabel.setTextSize(getResources().getDimension(R.dimen.car_title2_size));

        Collections.addAll(mButtons,
                BREAK_LINE,
                createButton(R.string.home, KeyEvent.KEYCODE_HOME),
                createButton(R.string.volume_up, KeyEvent.KEYCODE_VOLUME_UP),
                createButton(R.string.volume_down, KeyEvent.KEYCODE_VOLUME_DOWN),
                createButton(R.string.volume_mute, KeyEvent.KEYCODE_VOLUME_MUTE),
                createButton(R.string.voice, KeyEvent.KEYCODE_VOICE_ASSIST),
                BREAK_LINE,
                createButton(R.string.music, KeyEvent.KEYCODE_MUSIC),
                createButton(R.string.music_play, KeyEvent.KEYCODE_MEDIA_PLAY),
                createButton(R.string.music_stop, KeyEvent.KEYCODE_MEDIA_STOP),
                createButton(R.string.next_song, KeyEvent.KEYCODE_MEDIA_NEXT),
                createButton(R.string.prev_song, KeyEvent.KEYCODE_MEDIA_PREVIOUS),
                createButton(R.string.tune_right, KeyEvent.KEYCODE_CHANNEL_UP),
                createButton(R.string.tune_left, KeyEvent.KEYCODE_CHANNEL_DOWN),
                BREAK_LINE,
                createButton(R.string.call_send, KeyEvent.KEYCODE_CALL),
                createButton(R.string.call_end, KeyEvent.KEYCODE_ENDCALL),
                BREAK_LINE,
                steeringWheelLabel,
                BREAK_LINE,
                createButton(R.string.sw_left, KeyEvent.KEYCODE_DPAD_LEFT, INSTRUMENT_CLUSTER),
                createButton(R.string.sw_right, KeyEvent.KEYCODE_DPAD_RIGHT,
                        INSTRUMENT_CLUSTER),
                createButton(R.string.sw_up, KeyEvent.KEYCODE_DPAD_UP, INSTRUMENT_CLUSTER),
                createButton(R.string.sw_down, KeyEvent.KEYCODE_DPAD_DOWN, INSTRUMENT_CLUSTER),
                createButton(R.string.sw_center, KeyEvent.KEYCODE_DPAD_CENTER,
                        INSTRUMENT_CLUSTER),
                createButton(R.string.sw_back, KeyEvent.KEYCODE_BACK, INSTRUMENT_CLUSTER)
        );

        addButtonsToPanel(view.findViewById(R.id.input_buttons), mButtons);

        return view;
    }

    private Button createButton(@StringRes int textResId, int keyCode) {
        return createButton(textResId, keyCode, VehicleDisplay.MAIN);
    }

    private Button createButton(@StringRes int textResId, int keyCode, int targetDisplay) {
        Button button = new Button(getContext());
        button.setText(getContext().getString(textResId));
        button.setTextSize(getResources().getDimension(R.dimen.car_button_text_size));
        button.setOnClickListener(v -> onButtonClick(keyCode, targetDisplay));
        return button;
    }

    private void onButtonClick(int keyCode, int targetDisplay) {
        VehiclePropValue prop = new VehiclePropValue();
        prop.prop = sGenerateFakeDataControllingProperty;
        prop.value.int32Values.addAll(Lists.newArrayList(
                sKeyPressCommand, HW_KEY_INPUT, keyCode, targetDisplay));
        int status;
        try {
            status = mVehicle.set(prop);
        } catch (RemoteException e) {
            throw new RuntimeException("Failed to inject key press");
        }

        if (VehiclePropertyStatus.AVAILABLE != status) {
            Toast.makeText(getContext(), "Failed to inject key event, status:" + status,
                    Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mButtons.clear();
        if (mEventReaderService != null) {
            mEventReaderService.unregisterCallback(mKeypressEventHandler);
        }
        try {
            mVehicle.unsubscribe(mHalKeyEventHandler, HW_KEY_INPUT);
        } catch (RemoteException e) {
            Log.e(TAG, "failed to remove HAL registration for keypress events", e);
        }
    }

    private void addButtonsToPanel(LinearLayout root, List<View> buttons) {
        LinearLayout panel = null;
        for (View button : buttons) {
            if (button == BREAK_LINE || panel == null) {
                panel = new LinearLayout(getContext());
                panel.setOrientation(LinearLayout.HORIZONTAL);
                root.addView(panel);
            } else {
                panel.addView(button);
                panel.setPadding(0, 10, 10, 0);
            }
        }
    }
}
