// 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 main

import (
	"fmt"
	"io"
	"io/ioutil"
	"math"
	"os"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"time"

	"android.googlesource.com/platform/tools/gpu/client/adb"
	"android.googlesource.com/platform/tools/gpu/framework/log"
	"android.googlesource.com/platform/tools/gpu/framework/task"
)

// The input file is essentially a sparse table of integer values.
type inputProperty string
type inputEvent map[inputProperty]int
type inputEvents []inputEvent

var inputProperties []inputProperty

func registerInputPropery(prop string) inputProperty {
	inputProperties = append(inputProperties, inputProperty(prop))
	return inputProperty(prop)
}

var (
	// Display dimensions
	kOrientation = registerInputPropery("orientation")
	kWidth       = registerInputPropery("width")
	kHeight      = registerInputPropery("height")
	// Touch-screen dimensions
	kMinX = registerInputPropery("minX")
	kMaxX = registerInputPropery("maxX")
	kMinY = registerInputPropery("minY")
	kMaxY = registerInputPropery("maxY")
	// Frame statistics
	kTime          = registerInputPropery("time")
	kFrame         = registerInputPropery("frame")
	kDrawsPerFrame = registerInputPropery("drawsPerFrame")
	// Screen tap/swipe
	kX       = registerInputPropery("x")
	kY       = registerInputPropery("y")
	kPressed = registerInputPropery("pressed")
	// End of recording
	kEnd = registerInputPropery("end")
)

func writeEvent(out io.Writer, event inputEvent) {
	var line []string
	for _, name := range inputProperties {
		if value, ok := event[name]; ok {
			line = append(line, fmt.Sprintf("%s:%v", name, value))
		}
	}
	fmt.Fprintf(out, "%s\n", strings.Join(line, " "))
}

func parseEvent(line string) (inputEvent, error) {
	input := inputEvent{}
	for _, kvp := range strings.Split(line, " ") {
		if kvp != "" {
			parts := strings.Split(kvp, ":")
			if len(parts) == 2 {
				name := inputProperty(parts[0])
				value, err := strconv.Atoi(parts[1])
				if err != nil {
					return nil, err
				}
				input[name] = value
			} else {
				return nil, fmt.Errorf("Failed to parse key-value pair: '%s'", kvp)
			}
		}
	}
	return input, nil
}

// Implementation of the Writer interface which forwards the text to a lambda.
type lambdaWriter struct {
	f func(s string)
}

func (w *lambdaWriter) Write(p []byte) (n int, err error) {
	w.f(string(p))
	return len(p), nil
}

func atoi(s string) int {
	v, err := strconv.Atoi(s)
	if err != nil {
		panic(err)
	}
	return v
}

type frameInfo struct{ frame, drawsPerFrame int }

// Monitor logcat and parse frame statistics.
func monitorFrameStatistics(ctx log.Context, d adb.Device, out chan frameInfo) {
	re := regexp.MustCompile("NumFrames:([0-9]+).*NumDrawsPerFrame:([0-9]+)")
	stdout := &lambdaWriter{f: func(s string) {
		for _, match := range re.FindAllStringSubmatch(s, -1) {
			out <- frameInfo{frame: atoi(match[1]), drawsPerFrame: atoi(match[2])}
		}
	}}
	d.Command("logcat", "-T", "1", "-s", "GAPID:I").Capture(stdout, nil).Run(ctx)
	close(out)
}

type currentFrameInfo struct {
	value frameInfo
	mutex sync.Mutex
}

// Observe channel and make copy of the most recent value.
// We need to make copy of the channel to observe it.
func (info *currentFrameInfo) update(in <-chan frameInfo, out chan frameInfo) {
	for v := range in {
		info.mutex.Lock()
		info.value = v
		info.mutex.Unlock()
		if out != nil {
			out <- v
		}
	}
	if out != nil {
		close(out)
	}
}

func (info *currentFrameInfo) get() frameInfo {
	info.mutex.Lock()
	v := info.value
	info.mutex.Unlock()
	return v
}

// Write frame statistics into a file (rate limited).
func recordFrameStatistics(out io.Writer, in <-chan frameInfo) {
	const rate_limit = 10
	const min_change = 0.2
	startTime := time.Now()
	nextFrame, lastDrawsPerFrame := 0, 0
	for info := range in {
		// Emit statistics only if the number of draws changed significantly
		// and if it has been at least couple of frame since last time.
		change := float64(info.drawsPerFrame+1)/float64(lastDrawsPerFrame+1) - 1.0
		if info.frame >= nextFrame && math.Abs(change) >= min_change {
			t := int(time.Now().Sub(startTime).Seconds() * 1000)
			writeEvent(out, inputEvent{kTime: t, kFrame: info.frame, kDrawsPerFrame: info.drawsPerFrame})
			nextFrame = info.frame + rate_limit
			lastDrawsPerFrame = info.drawsPerFrame
		}
	}
}

type touchInfo struct{ x, y, pressed int }

// Monitor and parse touch screen events.
func monitorTouchScreen(ctx log.Context, d adb.Device, out chan touchInfo) {
	x, y, pressed := 0, 0, 0
	stdout := &lambdaWriter{f: func(s string) {
		for _, line := range strings.Split(s, "\n") {
			var device_id, value int
			var event_type, event_code string
			if _, err := fmt.Sscanf(line, "/dev/input/event%d: %s %s %x",
				&device_id, &event_type, &event_code, &value); err == nil {
				switch {
				case event_type == "EV_ABS" && event_code == "ABS_MT_POSITION_X":
					x, pressed = value, 1
				case event_type == "EV_ABS" && event_code == "ABS_MT_POSITION_Y":
					y, pressed = value, 1
				case event_type == "EV_SYN" && event_code == "SYN_REPORT":
					out <- touchInfo{x: x, y: y, pressed: pressed}
					pressed = 0
				}
			}
		}
	}}
	d.Shell("getevent", "-l").Capture(stdout, nil).Run(ctx)
	close(out)
}

// Write touch-screen events to file (rate limited).
// The touch event will also include the most recent frame information.
func recordTouchInfo(out io.Writer, currentInfo *currentFrameInfo, in <-chan touchInfo) {
	const rate_limit = 10
	startTime := time.Now()
	wasPressed, nextPressedFrame := 0, 0
	for info := range in {
		frameInfo := currentInfo.get()
		if wasPressed != info.pressed || (info.pressed == 1 && frameInfo.frame >= nextPressedFrame) {
			wasPressed = info.pressed
			t := int(time.Now().Sub(startTime).Seconds() * 1000)
			writeEvent(out, inputEvent{kTime: t,
				kFrame: frameInfo.frame, kDrawsPerFrame: frameInfo.drawsPerFrame,
				kX: info.x, kY: info.y, kPressed: info.pressed})
			nextPressedFrame = frameInfo.frame + rate_limit
		}
	}
}

func startRecordingInputs(ctx log.Context, d adb.Device, filename string) (cleanup func(), err error) {
	out, err := os.Create(filename)
	if err != nil {
		return nil, err
	}
	fmt.Fprintf(out, "# %s\n", strings.Join(os.Args, " "))

	// Record screen dimensions
	if orientation, width, height, ok := d.GetScreenDimensions(ctx); ok {
		writeEvent(out, inputEvent{kOrientation: orientation, kWidth: width, kHeight: height})
	}

	// Record touch dimensions
	if _, minX, maxX, minY, maxY, ok := d.GetTouchDimensions(ctx); ok {
		writeEvent(out, inputEvent{kMinX: minX, kMaxX: maxX, kMinY: minY, kMaxY: maxY})
	}

	touchInfos := make(chan touchInfo, 256)
	frameInfos := make(chan frameInfo, 256)
	frameInfosCopy := make(chan frameInfo, 256)
	stats := &currentFrameInfo{}

	go monitorTouchScreen(ctx, d, touchInfos)
	go monitorFrameStatistics(ctx, d, frameInfos)
	go stats.update(frameInfos, frameInfosCopy)
	go recordTouchInfo(out, stats, touchInfos)
	go recordFrameStatistics(out, frameInfosCopy)

	startTime := time.Now()
	return func() {
		t := int(time.Now().Sub(startTime).Seconds() * 1000)
		writeEvent(out, inputEvent{kTime: t, kEnd: 1})
	}, nil
}

func loadReplayInputs(filename string) (inputs inputEvents, err error) {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	for _, line := range strings.Split(string(data), "\n") {
		if !strings.HasPrefix(line, "#") {
			input, err := parseEvent(line)
			if err != nil {
				return nil, err
			}
			inputs = append(inputs, input)
		}
	}
	return
}

// Load given file and start replaying the user inputs.
// 'eof' will be signalled when the end of file is reached.
func startReplayingInputs(ctx log.Context, d adb.Device, replayInputsIn string, stop task.CancelFunc) error {
	inputs, err := loadReplayInputs(replayInputsIn)
	if err != nil {
		return err
	}
	deviceId, _, maxX, _, maxY, ok := d.GetTouchDimensions(ctx)
	if !ok {
		return fmt.Errorf("Faild to get touchscreen dimensions")
	}
	stats := currentFrameInfo{}
	frameInfos := make(chan frameInfo, 256)
	go monitorFrameStatistics(ctx, d, frameInfos)
	go stats.update(frameInfos, nil)
	go func() {
		ctx := ctx.Enter("Inputs")
		info := ctx.Info().Logf
		startTime := time.Now()
		time_drift := time.Duration(0)
		value_of := inputEvent{} // Keep track of most recent state.
		for _, input := range inputs {
			for k, v := range input {
				value_of[k] = v
			}
			if target, ok := input[kTime]; ok {
				// Wait for the minimum time
				current := time.Now().Sub(startTime)
				target := time.Duration(target)*time.Millisecond + time_drift
				if current < target {
					info("Wait until %.1fs", target.Seconds())
					time.Sleep(target - current)
				} else {
					time_drift = time_drift + current - target
					info("Time drift: %.1fs", time_drift.Seconds())
				}
			}
			if target, ok := input[kFrame]; ok {
				// Wait for the minimum frame
				for stats.get().frame < target {
					time_drift = time_drift + time.Second
					info("Wait for more frames (%v seen, %v needed, %.1fs drift)",
						stats.get().frame, target, time_drift.Seconds())
					time.Sleep(time.Second)
				}
			}
			if target, ok := input[kDrawsPerFrame]; ok {
				// Wait for the minimum draw count
				target = target - target/10 - 1
				for stats.get().drawsPerFrame < target {
					time_drift = time_drift + time.Second
					info("Wait for more draws (%v seen, %v needed, %.1fs drift)",
						stats.get().drawsPerFrame, target, time_drift.Seconds())
					time.Sleep(time.Second)
					target = target - target/10 - 1 // relax over time to ensure progress
				}
			}
			if pressed, ok := input[kPressed]; ok {
				// Press/release screen
				x, y := input[kX]*maxX/value_of[kMaxX], input[kY]*maxY/value_of[kMaxY]
				info("Touch: x:%v y:%v pressed:%v", x, y, pressed)
				d.SendTouch(ctx, deviceId, x, y, pressed != 0)
			}
			if end, ok := input[kEnd]; ok && end == 1 {
				stop()
				return
			}
		}
	}()
	return nil
}
