// 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 (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"time"

	"android.googlesource.com/platform/tools/gpu/client/adb"
	"android.googlesource.com/platform/tools/gpu/client/android"
	"android.googlesource.com/platform/tools/gpu/client/android/apk"
	"android.googlesource.com/platform/tools/gpu/client/bind"
	"android.googlesource.com/platform/tools/gpu/client/gapii"
	"android.googlesource.com/platform/tools/gpu/framework/app"
	"android.googlesource.com/platform/tools/gpu/framework/device"
	"android.googlesource.com/platform/tools/gpu/framework/file"
	"android.googlesource.com/platform/tools/gpu/framework/log"
	"android.googlesource.com/platform/tools/gpu/framework/task"
)

var (
	targetDevice    string
	duration        time.Duration
	output          string
	localPort       int
	observeFrames   uint
	observeDraws    uint
	disablePCS      bool
	recordErrors    bool
	clearCache      bool
	inputFile       string
	recordInputs    bool
	replayInputs    bool
	useLDPreload    bool
	apkPath         file.Path
	interceptorPath file.Path
	gapiiPath       file.Path
	vulkanLayerPath file.Path
)

func init() {
	verb := &app.Verb{
		Name:      "trace",
		ShortHelp: "Captures a gfx trace from an application",
		Run:       doTrace,
	}
	verb.Flags.StringVar(&targetDevice, "device", "", "the device to capture on")
	verb.Flags.DurationVar(&duration, "d", 0, "duration to trace for")
	verb.Flags.StringVar(&output, "out", "", "the file to generate")
	verb.Flags.IntVar(&localPort, "local", 0, "capture a local program instead of using ADB")
	verb.Flags.UintVar(&observeFrames, "observe-frames", 0, "capture the framebuffer every n frames (0 to disable)")
	verb.Flags.UintVar(&observeDraws, "observe-draws", 0, "capture the framebuffer every n draws (0 to disable)")
	verb.Flags.BoolVar(&disablePCS, "disable-pcs", false, "disable pre-compiled shaders")
	verb.Flags.BoolVar(&recordErrors, "record-errors", false, "record device error state")
	verb.Flags.BoolVar(&clearCache, "clear-cache", false, "clear package data before running it")
	verb.Flags.StringVar(&inputFile, "input-file", "", "the file to use for recorded inputs")
	verb.Flags.BoolVar(&recordInputs, "record-inputs", false, "record the inputs to file")
	verb.Flags.BoolVar(&replayInputs, "replay-inputs", false, "replay the inputs from file")
	verb.Flags.BoolVar(&useLDPreload, "ld-preload", false, "use LD_PRELOAD to register the interceptor library")
	verb.Flags.Var(&apkPath, "apk", "the path to an apk to install")
	verb.Flags.Var(&interceptorPath, "interceptor", "the path to the interceptor library")
	verb.Flags.Var(&gapiiPath, "gapii", "the path to the gapii library")
	verb.Flags.Var(&vulkanLayerPath, "vulkan-layer", "the path to the vulkan trace layer library")
	app.AddVerb(verb)
}

func doTrace(ctx log.Context, flags flag.FlagSet) error {
	options := gapii.Options{
		ObserveFrameFrequency: uint32(observeFrames),
		ObserveDrawFrequency:  uint32(observeDraws),
		APK:                   apkPath,
		Interceptor:           interceptorPath,
		Gapii:                 gapiiPath,
		VkLayer:               vulkanLayerPath,
	}

	if disablePCS {
		options.Flags |= gapii.DisablePrecompiledShaders
	}
	if recordErrors {
		options.Flags |= gapii.RecordErrorState
	}

	if localPort != 0 {
		return captureLocal(ctx, flags, localPort, options)
	}

	return captureADB(ctx, flags, options, useLDPreload)
}

func captureLocal(ctx log.Context, flags flag.FlagSet, port int, options gapii.Options) error {
	if output == "" {
		output = "capture.gfxtrace"
	}
	return capture(ctx, options, port, output)
}

// gapiiABI returns the ABI-flavor of GAPII to use given the device and package.
func gapiiABI(ctx log.Context, d bind.Device, info *apk.Information) device.ABI {
	for _, preferred := range d.Info().Configuration.ABIs {
		for _, abi := range info.ABI {
			if device.SameABI(preferred, *abi) {
				return preferred
			}
		}
	}
	return d.ABI() // Meh.
}

func captureADB(ctx log.Context, flags flag.FlagSet, options gapii.Options, useLDPreload bool) error {
	d, err := getADBDevice(ctx, targetDevice)
	if err != nil {
		return err
	}
	var a *android.Action
	if !options.APK.IsEmpty() {
		ctx.V("Source", options.APK).Print("Installing APK")
		data, err := ioutil.ReadFile(options.APK.System())
		if err != nil {
			return ctx.WrapError(err, "Read APK")
		}
		info, err := apk.Analyze(ctx, data)
		if err != nil {
			return ctx.WrapError(err, "Analyse APK")
		}
		if err := d.InstallAPK(ctx, options.APK.System(), true, true); err != nil {
			return ctx.WrapError(err, "Install APK")
		}
		pkg := &android.InstalledPackage{
			Name:       info.Name,
			Device:     d,
			ABI:        gapiiABI(ctx, d, info),
			Debuggable: info.Debuggable,
		}
		defer func() {
			ctx.Notice().V("apk", options.APK).Log("Uninstall APK")
			pkg.Uninstall(ctx)
		}()
		a = &android.Action{
			Name:     info.Action,
			Package:  pkg,
			Activity: info.Activity,
		}
	} else {
		if flags.NArg() != 1 {
			app.Usage(ctx, "Invalid number of arguments. Expected 1, got %d", flags.NArg())
			return nil
		}
		activity := flags.Arg(0)
		a, err = getAction(ctx, d, activity)
		if err != nil {
			return err
		}
	}

	if !useLDPreload && a.Package.Debuggable {
		ctx.Print("Package is debuggable")
	} else {
		err = d.Root(ctx)
		switch err {
		case nil:
		case adb.ErrDeviceNotRooted:
			return err
		default:
			return fmt.Errorf("Failed to restart ADB as root: %v", err)
		}
		ctx.Print("Device is rooted")
	}

	// Filenames - if no name specified, use package name.
	if output == "" {
		output = a.Package.Name + ".gfxtrace"
	}
	if inputFile == "" {
		inputFile = a.Package.Name + ".inputs"
	}

	if clearCache {
		ctx.Print("Clearing package cache")
		if err := a.Package.ClearCache(ctx); err != nil {
			return err
		}
	}

	if wasScreenOn, _ := d.IsScreenOn(ctx); !wasScreenOn {
		defer d.TurnScreenOff(ctx) // Think green!
	}

	start := gapii.JdwpStart
	if useLDPreload {
		start = gapii.AdbStart
	}

	libraries := gapii.NewLibraries()
	libraries.Set(gapii.LibInterceptor, options.Interceptor)
	libraries.Set(gapii.LibGapii, options.Gapii)
	libraries.Set(gapii.LibVkLayer, options.VkLayer)
	if err := libraries.Find(ctx, a); err != nil {
		return err
	}
	port, cleanup, err := start(ctx, libraries, a)
	if err != nil {
		return err
	}
	defer cleanup(ctx)

	ctx, stop := task.WithCancel(ctx)
	if recordInputs {
		ctx.Print("Starting input recorder")
		cleanup, err := startRecordingInputs(ctx, d, inputFile)
		if err != nil {
			return err
		}
		defer cleanup()
	} else if replayInputs {
		ctx.Print("Starting input replayer")
		if err := startReplayingInputs(ctx, d, inputFile, stop); err != nil {
			return err
		}
	}

	return capture(ctx, options, int(port), output)
}

func capture(ctx log.Context, options gapii.Options, port int, out string) error {
	ctx.Info().S("file", out).Log("Creating file")
	os.MkdirAll(filepath.Dir(out), 0755)
	file, err := os.Create(out)
	if err != nil {
		return err
	}
	defer file.Close()

	if duration == 0 {
		var cancel task.CancelFunc
		ctx, cancel = task.WithCancel(ctx)
		go func() {
			println("Press enter to stop capturing...")
			os.Stdin.Read([]byte{0})
			cancel()
		}()
	} else {
		ctx, _ = task.WithTimeout(ctx, duration)
	}
	_, err = gapii.Capture(ctx, port, file, options)
	if err != nil {
		return err
	}
	return nil
}

func getAction(ctx log.Context, d adb.Device, pattern string) (*android.Action, error) {
	re := regexp.MustCompile("(?i)" + pattern)
	packages, err := d.InstalledPackages(ctx)
	if err != nil {
		return nil, err
	}
	if len(packages) == 0 {
		return nil, fmt.Errorf("No packages found")
	}
	matchingActions := []*android.Action{}
	for _, p := range packages {
		for _, action := range p.Actions {
			if re.MatchString(action.String()) {
				matchingActions = append(matchingActions, action)
			}
		}
	}
	if len(matchingActions) == 0 {
		return nil, fmt.Errorf("No actions matching %s found", pattern)
	} else if len(matchingActions) > 1 {
		fmt.Println("Matching actions:")
		for _, test := range matchingActions {
			fmt.Print("    ")
			fmt.Println(test)
		}
		return nil, fmt.Errorf("Multiple actions matching %q found", pattern)
	}
	ctx.Info().WithValue("action", matchingActions[0]).Log("")
	return matchingActions[0], nil
}
