/*
 * Copyright (C) 2012 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.systemui.statusbar;

import java.io.BufferedWriter;
import java.io.FileDescriptor;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.LinkedList;

import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Slog;
import android.view.MotionEvent;

/**
 * Convenience class for capturing gestures for later analysis.
 */
public class GestureRecorder {
    public static final boolean DEBUG = true; // for now
    public static final String TAG = GestureRecorder.class.getSimpleName();

    public class Gesture {
        public abstract class Record {
            long time;
            public abstract String toJson();
        }
        public class MotionEventRecord extends Record {
            public MotionEvent event;
            public MotionEventRecord(long when, MotionEvent event) {
                this.time = when;
                this.event = event.copy();
            }
            String actionName(int action) {
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        return "down";
                    case MotionEvent.ACTION_UP:
                        return "up";
                    case MotionEvent.ACTION_MOVE:
                        return "move";
                    case MotionEvent.ACTION_CANCEL:
                        return "cancel";
                    default:
                        return String.valueOf(action);
                }
            }
            public String toJson() {
                return String.format(
                        ("{\"type\":\"motion\", \"time\":%d, \"action\":\"%s\", "
                            + "\"x\":%.2f, \"y\":%.2f, \"s\":%.2f, \"p\":%.2f}"),
                        this.time,
                        actionName(this.event.getAction()),
                        this.event.getRawX(),
                        this.event.getRawY(),
                        this.event.getSize(),
                        this.event.getPressure()
                        );
            }
        }
        public class TagRecord extends Record {
            public String tag, info;
            public TagRecord(long when, String tag, String info) {
                this.time = when;
                this.tag = tag;
                this.info = info;
            }
            public String toJson() {
                return String.format("{\"type\":\"tag\", \"time\":%d, \"tag\":\"%s\", \"info\":\"%s\"}",
                        this.time,
                        this.tag,
                        this.info
                        );
            }
        }
        private LinkedList<Record> mRecords = new LinkedList<Record>();
        private HashSet<String> mTags = new HashSet<String>();
        long mDownTime = -1;
        boolean mComplete = false;

        public void add(MotionEvent ev) {
            mRecords.add(new MotionEventRecord(ev.getEventTime(), ev));
            if (mDownTime < 0) {
                mDownTime = ev.getDownTime();
            } else {
                if (mDownTime != ev.getDownTime()) {
                    Slog.w(TAG, "Assertion failure in GestureRecorder: event downTime ("
                            +ev.getDownTime()+") does not match gesture downTime ("+mDownTime+")");
                }
            }
            switch (ev.getActionMasked()) {
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    mComplete = true;
            }
        }
        public void tag(long when, String tag, String info) {
            mRecords.add(new TagRecord(when, tag, info));
            mTags.add(tag);
        }
        public boolean isComplete() {
            return mComplete;
        }
        public String toJson() {
            StringBuilder sb = new StringBuilder();
            boolean first = true;
            sb.append("[");
            for (Record r : mRecords) {
                if (!first) sb.append(", ");
                first = false;
                sb.append(r.toJson());
            }
            sb.append("]");
            return sb.toString();
        }
    }

    // -=-=-=-=-=-=-=-=-=-=-=-

    static final long SAVE_DELAY = 5000; // ms
    static final int SAVE_MESSAGE = 6351;

    private LinkedList<Gesture> mGestures;
    private Gesture mCurrentGesture;
    private int mLastSaveLen = -1;
    private String mLogfile;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == SAVE_MESSAGE) {
                save();
            }
        }
    };

    public GestureRecorder(String filename) {
        mLogfile = filename;
        mGestures = new LinkedList<Gesture>();
        mCurrentGesture = null;
    }

    public void add(MotionEvent ev) {
        synchronized (mGestures) {
            if (mCurrentGesture == null || mCurrentGesture.isComplete()) {
                mCurrentGesture = new Gesture();
                mGestures.add(mCurrentGesture);
            }
            mCurrentGesture.add(ev);
        }
        saveLater();
    }

    public void tag(long when, String tag, String info) {
        synchronized (mGestures) {
            if (mCurrentGesture == null) {
                mCurrentGesture = new Gesture();
                mGestures.add(mCurrentGesture);
            }
            mCurrentGesture.tag(when, tag, info);
        }
        saveLater();
    }

    public void tag(long when, String tag) {
        tag(when, tag, null);
    }

    public void tag(String tag) {
        tag(SystemClock.uptimeMillis(), tag, null);
    }

    public void tag(String tag, String info) {
        tag(SystemClock.uptimeMillis(), tag, info);
    }

    /**
     * Generates a JSON string capturing all completed gestures.
     * Not threadsafe; call with a lock.
     */
    public String toJsonLocked() {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        sb.append("[");
        int count = 0;
        for (Gesture g : mGestures) {
            if (!g.isComplete()) continue;
            if (!first) sb.append("," );
            first = false;
            sb.append(g.toJson());
            count++;
        }
        mLastSaveLen = count;
        sb.append("]");
        return sb.toString();
    }

    public String toJson() {
        String s;
        synchronized (mGestures) {
            s = toJsonLocked();
        }
        return s;
    }

    public void saveLater() {
        mHandler.removeMessages(SAVE_MESSAGE);
        mHandler.sendEmptyMessageDelayed(SAVE_MESSAGE, SAVE_DELAY);
    }

    public void save() {
        synchronized (mGestures) {
            try {
                BufferedWriter w = new BufferedWriter(new FileWriter(mLogfile, /*append=*/ true));
                w.append(toJsonLocked() + "\n");
                w.close();
                mGestures.clear();
                // If we have a pending gesture, push it back
                if (mCurrentGesture != null && !mCurrentGesture.isComplete()) {
                    mGestures.add(mCurrentGesture);
                }
                if (DEBUG) {
                    Slog.v(TAG, String.format("Wrote %d complete gestures to %s", mLastSaveLen, mLogfile));
                }
            } catch (IOException e) {
                Slog.e(TAG, String.format("Couldn't write gestures to %s", mLogfile), e);
                mLastSaveLen = -1;
            }
        }
    }

    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        save();
        if (mLastSaveLen >= 0) {
            pw.println(String.valueOf(mLastSaveLen) + " gestures written to " + mLogfile);
        } else {
            pw.println("error writing gestures");
        }
    }
}
