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

import (
	"bytes"
	"io/ioutil"
	"testing"

	"android.googlesource.com/platform/tools/gpu/client/gapii"
	"android.googlesource.com/platform/tools/gpu/framework/assert"
	"android.googlesource.com/platform/tools/gpu/framework/binary"
	"android.googlesource.com/platform/tools/gpu/framework/binary/cyclic"
	"android.googlesource.com/platform/tools/gpu/framework/binary/vle"

	_ "android.googlesource.com/platform/tools/gpu/gapid/gfxapi/gles"
)

const (
	testfile       = "./testdata/EpicCitadel.gfxtrace"
	expected_atoms = 327727
)

var (
	buf      []byte
	atomsBuf []byte
)

// LoadFile load the trace file if it has been loaded already
func LoadFile(b *testing.B) []byte {
	if buf != nil {
		return buf
	}
	if lbuf, err := ioutil.ReadFile(testfile); err != nil {
		b.Fatalf("Failed to read test data: %v: %v", testfile, err)
		return nil
	} else {
		buf = lbuf
		return buf
	}
}

// BuildAtomBuf reads the capture file and re-encodes only the atoms
func BuildAtomBuf(b *testing.B) []byte {
	if atomsBuf != nil {
		return atomsBuf
	}
	buf = LoadFile(b)
	reader := bytes.NewBuffer(buf)
	atoms, err := gapii.ReadCapture(assert.Context(b), reader)
	if err != nil {
		b.Fatalf("Failed to read capture for buildAtomBuf %v", err)
		return nil
	}
	if len(atoms.Atoms) != expected_atoms {
		b.Fatalf("Expected %v atoms got %v", expected_atoms, len(atoms.Atoms))
		return nil
	}
	writer := &bytes.Buffer{}
	encoder := cyclic.Encoder(vle.Writer(writer))
	encoder.String(gapii.CaptureTag)
	for _, atom := range atoms.Atoms {
		encoder.Variant(atom)
		if encoder.Error() != nil {
			b.Fatalf("Failed to read encode atoms %v", encoder.Error())
		}
	}
	atomsBuf = writer.Bytes()
	return atomsBuf
}

// ReadCaptureBench, used to benchmark gapii.ReadCapture
func ReadCaptureBench(buf []byte, b *testing.B) {
	reader := bytes.NewBuffer(buf)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, err := gapii.ReadCapture(assert.Context(b), reader)
		if err != nil {
			b.Fatalf("read capture returned error: %v", err)
		}
	}
}

func DecodeRealFile(buf []byte, b *testing.B) {
	decoder := cyclic.Decoder(vle.Reader(bytes.NewBuffer(buf)))
	// We don't bother to check the capture version string. If the test
	// fails because you are making a breaking change to the format
	// that is good to know.
	var obj []binary.Object
	b.ResetTimer()
	for i := 0; i < b.N && decoder.Error() == nil; i++ {
		// Don't worry about the cost of the append as any real capture
		// file reader will have a similar cost.
		obj = append(obj, decoder.Variant())
	}
	if decoder.Error() != nil {
		b.Fatalf("Error decoding %v", decoder.Error())
	}
	if len(obj) != b.N {
		b.Errorf("Expect number of objects %v got %v", b.N, len(obj))
	}
}
