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

import (
	"fmt"
	"io"
	"math"
	"net"
	"time"

	"android.googlesource.com/platform/tools/gpu/framework/binary/cyclic"
	"android.googlesource.com/platform/tools/gpu/framework/binary/schema"
	"android.googlesource.com/platform/tools/gpu/framework/binary/vle"
	"android.googlesource.com/platform/tools/gpu/framework/file"
	"android.googlesource.com/platform/tools/gpu/framework/log"
	"android.googlesource.com/platform/tools/gpu/framework/task"
	"android.googlesource.com/platform/tools/gpu/gapid/atom"
)

// CaptureTag is the trace file header tag.
const CaptureTag = "GapiiTraceFile_V1.1"

// Flags is a bit-field of flags to use when creating a capture.
type Flags uint32

const (
	// DisablePrecompiledShaders fakes no support for PCS, forcing the app to
	// share shader source.
	DisablePrecompiledShaders Flags = 0x00000001
	// RecordErrorState queries the driver error state after each all and stores
	// errors as extras.
	RecordErrorState Flags = 0x10000000
)

// Options to use when creating a capture.
type Options struct {
	// If non-zero, then a framebuffer-observation will be made after every n end-of-frames.
	ObserveFrameFrequency uint32
	// If non-zero, then a framebuffer-observation will be made after every n draw calls.
	ObserveDrawFrequency uint32
	// Combination of FlagXX bits.
	Flags Flags
	// APK is an apk to install before tracing
	APK file.Path
	// Interceptor is the path to an interceptor.so to use
	Interceptor file.Path
	// Gapii is the path to an libgapii.so to use
	Gapii file.Path
	// VkLayer is the path to the vulkan tracing layer to use
	VkLayer file.Path
}

const sizeGap = 1024 * 1024 * 5
const timeGap = time.Second

type siSize int64

var formats = []string{
	"%.0fB",
	"%.2fKB",
	"%.2fMB",
	"%.2fGB",
	"%.2fTB",
	"%.2fPB",
	"%.2fEB",
}

func (s siSize) String() string {
	if s == 0 {
		return "0.0B"
	}
	size := float64(s)
	e := math.Floor(math.Log(size) / math.Log(1000))
	f := formats[int(e)]
	v := math.Floor(size/math.Pow(1000, e)*10+0.5) / 10
	return fmt.Sprintf(f, v)
}

func capture(ctx log.Context, port int, w io.Writer, o Options) (int64, error) {
	if task.Stopped(ctx) {
		return 0, nil
	}
	conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", port))
	if err != nil {
		return 0, nil // Treat failure-to-connect as target-not-ready instead of an error.
	}
	defer conn.Close()
	if err := sendHeader(conn, o); err != nil {
		return 0, ctx.WrapError(err, "Header send failed")
	}

	var count, nextSize siSize
	startTime := time.Now()
	nextTime := startTime
	for {
		if task.Stopped(ctx) {
			ctx.Printf("Stop: %v", count)
			break
		}
		now := time.Now()
		conn.SetReadDeadline(now.Add(time.Millisecond * 100)) // Allow for stop event and UI refreshes.
		n, err := io.CopyN(w, conn, 1024*64)
		count += siSize(n)
		switch {
		case err == io.EOF:
			// End of stream. End.
			ctx.Printf("EOF: %v", count)
			return int64(count), nil
		case err != nil && count > 0:
			err, isnet := err.(net.Error)
			if !isnet || (!err.Temporary() && !err.Timeout()) {
				ctx.Info().Fail(err, "Connection error")
				// Got an error mid-stream terminate.
				return int64(count), err
			}
		case err != nil && count == 0:
			// Got an error without receiving a byte of data.
			// Treat failure-to-connect as target-not-ready instead of an error.
			return 0, nil
		}
		if count > nextSize || now.After(nextTime) {
			nextSize = count + sizeGap
			nextTime = now.Add(timeGap)
			delta := time.Duration(int64(now.Sub(startTime)/time.Millisecond)) * time.Millisecond
			ctx.Printf("Capturing: %v in %v", count, delta)
		}
	}
	return int64(count), nil
}

// Capture opens up the specified port and then waits for a capture to be
// delivered using the specified capture options.
// It copies the capture into the supplied writer.
func Capture(ctx log.Context, port int, w io.Writer, options Options) (int64, error) {
	ctx.Printf("Waiting for connection to localhost:%d...", port)
	for {
		count, err := capture(ctx, port, w, options)
		if err != nil {
			return count, err
		}
		if count != 0 {
			return count, nil
		}
		// ADB has an annoying tendancy to insta-close forwarded sockets when
		// there's no application waiting for the connection. Treat this as
		// another waiting-for-connection case.
		select {
		case <-task.ShouldStop(ctx):
			ctx.Print("Aborted.")
			return 0, nil
		case <-time.After(500 * time.Millisecond):
			ctx.Print("Retry...")
		}
	}
}

// ReadCapture converts the contents of a capture stream to an atom list.
func ReadCapture(ctx log.Context, in io.Reader) (*atom.List, error) {
	list := atom.NewList()
	d := cyclic.Decoder(vle.Reader(in))
	tag := d.String()
	if d.Error() != nil {
		return list, d.Error()
	}
	if tag != CaptureTag {
		return list, fmt.Errorf("Invalid capture tag '%s'", tag)
	}
	for {
		obj := d.Variant()
		if d.Error() != nil {
			if d.Error() != io.EOF {
				ctx.Warning().I("len", len(list.Atoms)).Fail(d.Error(), "Decode of capture errored")
				if len(list.Atoms) > 0 {
					a := list.Atoms[len(list.Atoms)-1]
					ctx.Notice().V("atom", a).Log("Last atom successfully decoded")
				}
			}
			break
		}
		switch obj := obj.(type) {
		case atom.Atom:
			list.Atoms = append(list.Atoms, obj)
		case *schema.Object:
			a, err := atom.Wrap(obj)
			if err != nil {
				return list, err
			}
			list.Atoms = append(list.Atoms, a)
		default:
			return list, fmt.Errorf("Expected atom, got '%T' after decoding %d atoms", obj, len(list.Atoms))
		}
	}
	return list, nil
}
