/*
 * Copyright 2015 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 android.hardware.input.cts.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import android.app.Instrumentation;
import android.app.UiAutomation;
import android.hardware.input.cts.InputCallback;
import android.hardware.input.cts.InputCtsActivity;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.view.KeyEvent;
import android.view.MotionEvent;

import androidx.test.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;

import libcore.io.IoUtils;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class InputTestCase {
    // hid executable expects "-" argument to read from stdin instead of a file
    private static final String HID_COMMAND = "hid -";
    private static final String[] KEY_ACTIONS = {"DOWN", "UP", "MULTIPLE"};

    private OutputStream mOutputStream;

    private final BlockingQueue<KeyEvent> mKeys;
    private final BlockingQueue<MotionEvent> mMotions;
    private InputListener mInputListener;

    private Instrumentation mInstrumentation;

    private volatile CountDownLatch mDeviceAddedSignal; // to wait for onInputDeviceAdded signal

    public InputTestCase() {
        mKeys = new LinkedBlockingQueue<KeyEvent>();
        mMotions = new LinkedBlockingQueue<MotionEvent>();
        mInputListener = new InputListener();
    }

    @Rule
    public ActivityTestRule<InputCtsActivity> mActivityRule =
        new ActivityTestRule<>(InputCtsActivity.class);

    @Before
    public void setUp() throws Exception {
        clearKeys();
        clearMotions();
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        mActivityRule.getActivity().setInputCallback(mInputListener);
        setupPipes();
    }

    @After
    public void tearDown() throws Exception {
        IoUtils.closeQuietly(mOutputStream);
    }

    /**
     * Register an input device. May cause a failure if the device added notification
     * is not received within the timeout period
     *
     * @param resourceId The resource id from which to send the register command.
     */
    public void registerInputDevice(int resourceId) {
        mDeviceAddedSignal = new CountDownLatch(1);
        sendHidCommands(resourceId);
        try {
            // Found that in kernel 3.10, the device registration takes a very long time
            // The wait can be decreased to 2 seconds after kernel 3.10 is no longer supported
            mDeviceAddedSignal.await(20L, TimeUnit.SECONDS);
            if (mDeviceAddedSignal.getCount() != 0) {
                fail("Device added notification was not received in time.");
            }
        } catch (InterruptedException ex) {
            fail("Unexpectedly interrupted while waiting for device added notification.");
        }
        SystemClock.sleep(100);
    }

    /**
     * Sends the HID commands designated by the given resource id.
     * The commands must be in the format expected by the `hid` shell command.
     *
     * @param id The resource id from which to load the HID commands. This must be a "raw"
     * resource.
     */
    public void sendHidCommands(int id) {
        try {
            mOutputStream.write(getEvents(id).getBytes());
            mOutputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Asserts that the application received a {@link android.view.KeyEvent} with the given action
     * and keycode.
     *
     * If other KeyEvents are received by the application prior to the expected KeyEvent, or no
     * KeyEvents are received within a reasonable amount of time, then this will throw an
     * AssertionFailedError.
     *
     * @param action The action to expect on the next KeyEvent
     * (e.g. {@link android.view.KeyEvent#ACTION_DOWN}).
     * @param keyCode The expected key code of the next KeyEvent.
     */
    public void assertReceivedKeyEvent(int action, int keyCode) {
        KeyEvent k = waitForKey();
        if (k == null) {
            fail("Timed out waiting for " + KeyEvent.keyCodeToString(keyCode)
                    + " with action " + KEY_ACTIONS[action]);
            return;
        }
        assertEquals(action, k.getAction());
        assertEquals(keyCode, k.getKeyCode());
    }

    /**
     * Asserts that no more events have been received by the application.
     *
     * If any more events have been received by the application, this throws an
     * AssertionFailedError.
     */
    public void assertNoMoreEvents() {
        KeyEvent key;
        MotionEvent motion;
        if ((key = mKeys.poll()) != null) {
            fail("Extraneous key events generated: " + key);
        }
        if ((motion = mMotions.poll()) != null) {
            fail("Extraneous motion events generated: " + motion);
        }
    }

    private KeyEvent waitForKey() {
        try {
            return mKeys.poll(1, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            return null;
        }
    }

    private void clearKeys() {
        mKeys.clear();
    }

    private void clearMotions() {
        mMotions.clear();
    }

    private void setupPipes() throws IOException {
        UiAutomation ui = mInstrumentation.getUiAutomation();
        ParcelFileDescriptor[] pipes = ui.executeShellCommandRw(HID_COMMAND);

        mOutputStream = new ParcelFileDescriptor.AutoCloseOutputStream(pipes[1]);
        IoUtils.closeQuietly(pipes[0]); // hid command is write-only
    }

    private String getEvents(int id) throws IOException {
        InputStream is =
            mInstrumentation.getTargetContext().getResources().openRawResource(id);
        return readFully(is);
    }

    private static String readFully(InputStream is) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int read = 0;
        byte[] buffer = new byte[1024];
        while ((read = is.read(buffer)) >= 0) {
            baos.write(buffer, 0, read);
        }
        return baos.toString();
    }

    private class InputListener implements InputCallback {
        @Override
        public void onKeyEvent(KeyEvent ev) {
            boolean done = false;
            do {
                try {
                    mKeys.put(new KeyEvent(ev));
                    done = true;
                } catch (InterruptedException ignore) { }
            } while (!done);
        }

        @Override
        public void onMotionEvent(MotionEvent ev) {
            boolean done = false;
            do {
                try {
                    mMotions.put(MotionEvent.obtain(ev));
                    done = true;
                } catch (InterruptedException ignore) { }
            } while (!done);
        }

        @Override
        public void onInputDeviceAdded(int deviceId) {
            mDeviceAddedSignal.countDown();
        }

        @Override
        public void onInputDeviceRemoved(int deviceId) {
        }

        @Override
        public void onInputDeviceChanged(int deviceId) {
        }
    }


}
