/*
 * Copyright (C) 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 com.android.commands.hid;

import android.util.JsonReader;
import android.util.JsonToken;
import android.util.Log;

import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

public class Event {
    private static final String TAG = "HidEvent";

    public static final String COMMAND_REGISTER = "register";
    public static final String COMMAND_DELAY = "delay";
    public static final String COMMAND_REPORT = "report";

    private int mId;
    private String mCommand;
    private String mName;
    private byte[] mDescriptor;
    private int mVid;
    private int mPid;
    private byte[] mReport;
    private int mDuration;

    public int getId() {
        return mId;
    }

    public String getCommand() {
        return mCommand;
    }

    public String getName() {
        return mName;
    }

    public byte[] getDescriptor() {
        return mDescriptor;
    }

    public int getVendorId() {
        return mVid;
    }

    public int getProductId() {
        return mPid;
    }

    public byte[] getReport() {
        return mReport;
    }

    public int getDuration() {
        return mDuration;
    }

    public String toString() {
        return "Event{id=" + mId
            + ", command=" + String.valueOf(mCommand)
            + ", name=" + String.valueOf(mName)
            + ", descriptor=" + Arrays.toString(mDescriptor)
            + ", vid=" + mVid
            + ", pid=" + mPid
            + ", report=" + Arrays.toString(mReport)
            + ", duration=" + mDuration
            + "}";
    }

    private static class Builder {
        private Event mEvent;

        public Builder() {
            mEvent = new Event();
        }

        public void setId(int id) {
            mEvent.mId = id;
        }

        private void setCommand(String command) {
            mEvent.mCommand = command;
        }

        public void setName(String name) {
            mEvent.mName = name;
        }

        public void setDescriptor(byte[] descriptor) {
            mEvent.mDescriptor = descriptor;
        }

        public void setReport(byte[] report) {
            mEvent.mReport = report;
        }

        public void setVid(int vid) {
            mEvent.mVid = vid;
        }

        public void setPid(int pid) {
            mEvent.mPid = pid;
        }

        public void setDuration(int duration) {
            mEvent.mDuration = duration;
        }

        public Event build() {
            if (mEvent.mId == -1) {
                throw new IllegalStateException("No event id");
            } else if (mEvent.mCommand == null) {
                throw new IllegalStateException("Event does not contain a command");
            }
            if (COMMAND_REGISTER.equals(mEvent.mCommand)) {
                if (mEvent.mDescriptor == null) {
                    throw new IllegalStateException("Device registration is missing descriptor");
                }
            } else if (COMMAND_DELAY.equals(mEvent.mCommand)) {
                if (mEvent.mDuration <= 0) {
                    throw new IllegalStateException("Delay has missing or invalid duration");
                }
            } else if (COMMAND_REPORT.equals(mEvent.mCommand)) {
                if (mEvent.mReport == null) {
                    throw new IllegalStateException("Report command is missing report data");
                }
            }
            return mEvent;
        }
    }

    public static class Reader {
        private JsonReader mReader;

        public Reader(InputStreamReader in) {
            mReader = new JsonReader(in);
            mReader.setLenient(true);
        }

        public Event getNextEvent() throws IOException {
            Event e = null;
            while (e == null && mReader.peek() != JsonToken.END_DOCUMENT) {
                Event.Builder eb = new Event.Builder();
                try {
                    mReader.beginObject();
                    while (mReader.hasNext()) {
                        String name = mReader.nextName();
                        switch (name) {
                            case "id":
                                eb.setId(readInt());
                                break;
                            case "command":
                                eb.setCommand(mReader.nextString());
                                break;
                            case "descriptor":
                                eb.setDescriptor(readData());
                                break;
                            case "name":
                                eb.setName(mReader.nextString());
                                break;
                            case "vid":
                                eb.setVid(readInt());
                                break;
                            case "pid":
                                eb.setPid(readInt());
                                break;
                            case "report":
                                eb.setReport(readData());
                                break;
                            case "duration":
                                eb.setDuration(readInt());
                                break;
                            default:
                                mReader.skipValue();
                        }
                    }
                    mReader.endObject();
                } catch (IllegalStateException ex) {
                    error("Error reading in object, ignoring.", ex);
                    consumeRemainingElements();
                    mReader.endObject();
                    continue;
                }
                e = eb.build();
            }

            return e;
        }

        private byte[] readData() throws IOException {
            ArrayList<Integer> data = new ArrayList<Integer>();
            try {
                mReader.beginArray();
                while (mReader.hasNext()) {
                    data.add(Integer.decode(mReader.nextString()));
                }
                mReader.endArray();
            } catch (IllegalStateException|NumberFormatException e) {
                consumeRemainingElements();
                mReader.endArray();
                throw new IllegalStateException("Encountered malformed data.", e);
            }
            byte[] rawData = new byte[data.size()];
            for (int i = 0; i < data.size(); i++) {
                int d = data.get(i);
                if ((d & 0xFF) != d) {
                    throw new IllegalStateException("Invalid data, all values must be byte-sized");
                }
                rawData[i] = (byte)d;
            }
            return rawData;
        }

        private int readInt() throws IOException {
            String val = mReader.nextString();
            return Integer.decode(val);
        }

        private void consumeRemainingElements() throws IOException {
            while (mReader.hasNext()) {
                mReader.skipValue();
            }
        }
    }

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

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