/*
 * Copyright (C) 2020 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.commands.uinput;

import android.util.Log;
import android.util.SparseArray;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

/**
 * Uinput class encapsulates execution of "uinput" command. It parses the provided input stream
 * parameters as JSON file format, extract event entries and perform commands of event entries.
 * Uinput device will be created when performing registration command and used to inject events.
 */
public class Uinput {
    private static final String TAG = "UINPUT";

    private final Event.Reader mReader;
    private final SparseArray<Device> mDevices;

    private static void usage() {
        error("Usage: uinput [FILE]");
    }

    /**
     * Commandline "uinput" binary main entry
     */
    public static void main(String[] args) {
        if (args.length != 1) {
            usage();
            System.exit(1);
        }

        InputStream stream = null;
        try {
            if (args[0].equals("-")) {
                stream = System.in;
            } else {
                File f = new File(args[0]);
                stream = new FileInputStream(f);
            }
            (new Uinput(stream)).run();
        } catch (Exception e) {
            error("Uinput injection failed.", e);
            System.exit(1);
        } finally {
            try {
                stream.close();
            } catch (IOException e) {
            }
        }
    }

    private Uinput(InputStream in) {
        mDevices = new SparseArray<Device>();
        try {
            mReader = new Event.Reader(new InputStreamReader(in, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    private void run() {
        try {
            Event e = null;
            while ((e = mReader.getNextEvent()) != null) {
                process(e);
            }
        } catch (IOException ex) {
            error("Error reading in events.", ex);
        }

        for (int i = 0; i < mDevices.size(); i++) {
            mDevices.valueAt(i).close();
        }
    }

    private void process(Event e) {
        final int index = mDevices.indexOfKey(e.getId());
        if (index >= 0) {
            Device d = mDevices.valueAt(index);
            if (Event.COMMAND_DELAY.equals(e.getCommand())) {
                d.addDelay(e.getDuration());
            } else if (Event.COMMAND_INJECT.equals(e.getCommand())) {
                d.injectEvent(e.getInjections());
            } else {
                if (Event.COMMAND_REGISTER.equals(e.getCommand())) {
                    error("Device id=" + e.getId() + " is already registered. Ignoring event.");
                } else {
                    error("Unknown command \"" + e.getCommand() + "\". Ignoring event.");
                }
            }
        } else if (Event.COMMAND_REGISTER.equals(e.getCommand())) {
            registerDevice(e);
        } else {
            Log.e(TAG, "Unknown device id specified. Ignoring event.");
        }
    }

    private void registerDevice(Event e) {
        if (!Event.COMMAND_REGISTER.equals(e.getCommand())) {
            throw new IllegalStateException(
                    "Tried to send command \"" + e.getCommand() + "\" to an unregistered device!");
        }
        int id = e.getId();
        Device d = new Device(id, e.getName(), e.getVendorId(), e.getProductId(), e.getBus(),
                e.getConfiguration(), e.getFfEffectsMax(), e.getAbsInfo());
        mDevices.append(id, d);
    }

    private static void error(String msg) {
        error(msg, null);
    }

    private static void error(String msg, Exception e) {
        Log.e(TAG, msg);
        if (e != null) {
            Log.e(TAG, Log.getStackTraceString(e));
        }
    }
}
