// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package test

import (
	"fmt"
	"internal/coverage"
	"internal/coverage/decodemeta"
	"internal/coverage/encodemeta"
	"internal/coverage/slicewriter"
	"os"
	"path/filepath"
	"testing"
)

func cmpFuncDesc(want, got coverage.FuncDesc) string {
	swant := fmt.Sprintf("%+v", want)
	sgot := fmt.Sprintf("%+v", got)
	if swant == sgot {
		return ""
	}
	return fmt.Sprintf("wanted %q got %q", swant, sgot)
}

func TestMetaDataEmptyPackage(t *testing.T) {
	// Make sure that encoding/decoding works properly with packages
	// that don't actually have any functions.
	p := "empty/package"
	pn := "package"
	mp := "m"
	b, err := encodemeta.NewCoverageMetaDataBuilder(p, pn, mp)
	if err != nil {
		t.Fatalf("making builder: %v", err)
	}
	drws := &slicewriter.WriteSeeker{}
	b.Emit(drws)
	drws.Seek(0, os.SEEK_SET)
	dec, err := decodemeta.NewCoverageMetaDataDecoder(drws.BytesWritten(), false)
	if err != nil {
		t.Fatalf("making decoder: %v", err)
	}
	nf := dec.NumFuncs()
	if nf != 0 {
		t.Errorf("dec.NumFuncs(): got %d want %d", nf, 0)
	}
	pp := dec.PackagePath()
	if pp != p {
		t.Errorf("dec.PackagePath(): got %s want %s", pp, p)
	}
	ppn := dec.PackageName()
	if ppn != pn {
		t.Errorf("dec.PackageName(): got %s want %s", ppn, pn)
	}
	pmp := dec.ModulePath()
	if pmp != mp {
		t.Errorf("dec.ModulePath(): got %s want %s", pmp, mp)
	}
}

func TestMetaDataEncoderDecoder(t *testing.T) {
	// Test encode path.
	pp := "foo/bar/pkg"
	pn := "pkg"
	mp := "barmod"
	b, err := encodemeta.NewCoverageMetaDataBuilder(pp, pn, mp)
	if err != nil {
		t.Fatalf("making builder: %v", err)
	}
	f1 := coverage.FuncDesc{
		Funcname: "func",
		Srcfile:  "foo.go",
		Units: []coverage.CoverableUnit{
			coverage.CoverableUnit{StLine: 1, StCol: 2, EnLine: 3, EnCol: 4, NxStmts: 5},
			coverage.CoverableUnit{StLine: 6, StCol: 7, EnLine: 8, EnCol: 9, NxStmts: 10},
		},
	}
	idx := b.AddFunc(f1)
	if idx != 0 {
		t.Errorf("b.AddFunc(f1) got %d want %d", idx, 0)
	}

	f2 := coverage.FuncDesc{
		Funcname: "xfunc",
		Srcfile:  "bar.go",
		Units: []coverage.CoverableUnit{
			coverage.CoverableUnit{StLine: 1, StCol: 2, EnLine: 3, EnCol: 4, NxStmts: 5},
			coverage.CoverableUnit{StLine: 6, StCol: 7, EnLine: 8, EnCol: 9, NxStmts: 10},
			coverage.CoverableUnit{StLine: 11, StCol: 12, EnLine: 13, EnCol: 14, NxStmts: 15},
		},
	}
	idx = b.AddFunc(f2)
	if idx != 1 {
		t.Errorf("b.AddFunc(f2) got %d want %d", idx, 0)
	}

	// Emit into a writer.
	drws := &slicewriter.WriteSeeker{}
	b.Emit(drws)

	// Test decode path.
	drws.Seek(0, os.SEEK_SET)
	dec, err := decodemeta.NewCoverageMetaDataDecoder(drws.BytesWritten(), false)
	if err != nil {
		t.Fatalf("NewCoverageMetaDataDecoder error: %v", err)
	}
	nf := dec.NumFuncs()
	if nf != 2 {
		t.Errorf("dec.NumFuncs(): got %d want %d", nf, 2)
	}

	gotpp := dec.PackagePath()
	if gotpp != pp {
		t.Errorf("packagepath: got %s want %s", gotpp, pp)
	}
	gotpn := dec.PackageName()
	if gotpn != pn {
		t.Errorf("packagename: got %s want %s", gotpn, pn)
	}

	cases := []coverage.FuncDesc{f1, f2}
	for i := uint32(0); i < uint32(len(cases)); i++ {
		var fn coverage.FuncDesc
		if err := dec.ReadFunc(i, &fn); err != nil {
			t.Fatalf("err reading function %d: %v", i, err)
		}
		res := cmpFuncDesc(cases[i], fn)
		if res != "" {
			t.Errorf("ReadFunc(%d): %s", i, res)
		}
	}
}

func createFuncs(i int) []coverage.FuncDesc {
	res := []coverage.FuncDesc{}
	lc := uint32(1)
	for fi := 0; fi < i+1; fi++ {
		units := []coverage.CoverableUnit{}
		for ui := 0; ui < (fi+1)*(i+1); ui++ {
			units = append(units,
				coverage.CoverableUnit{StLine: lc, StCol: lc + 1,
					EnLine: lc + 2, EnCol: lc + 3, NxStmts: lc + 4,
				})
			lc += 5
		}
		f := coverage.FuncDesc{
			Funcname: fmt.Sprintf("func_%d_%d", i, fi),
			Srcfile:  fmt.Sprintf("foo_%d.go", i),
			Units:    units,
		}
		res = append(res, f)
	}
	return res
}

func createBlob(t *testing.T, i int) []byte {
	nomodule := ""
	b, err := encodemeta.NewCoverageMetaDataBuilder("foo/pkg", "pkg", nomodule)
	if err != nil {
		t.Fatalf("making builder: %v", err)
	}

	funcs := createFuncs(i)
	for _, f := range funcs {
		b.AddFunc(f)
	}
	drws := &slicewriter.WriteSeeker{}
	b.Emit(drws)
	return drws.BytesWritten()
}

func createMetaDataBlobs(t *testing.T, nb int) [][]byte {
	res := [][]byte{}
	for i := 0; i < nb; i++ {
		res = append(res, createBlob(t, i))
	}
	return res
}

func TestMetaDataWriterReader(t *testing.T) {
	d := t.TempDir()

	// Emit a meta-file...
	mfpath := filepath.Join(d, "covmeta.hash.0")
	of, err := os.OpenFile(mfpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
	if err != nil {
		t.Fatalf("opening covmeta: %v", err)
	}
	//t.Logf("meta-file path is %s", mfpath)
	blobs := createMetaDataBlobs(t, 7)
	gran := coverage.CtrGranularityPerBlock
	mfw := encodemeta.NewCoverageMetaFileWriter(mfpath, of)
	finalHash := [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
	err = mfw.Write(finalHash, blobs, coverage.CtrModeAtomic, gran)
	if err != nil {
		t.Fatalf("writing meta-file: %v", err)
	}
	if err = of.Close(); err != nil {
		t.Fatalf("closing meta-file: %v", err)
	}

	// ... then read it back in, first time without setting fileView,
	// second time setting it.
	for k := 0; k < 2; k++ {
		var fileView []byte

		inf, err := os.Open(mfpath)
		if err != nil {
			t.Fatalf("open() on meta-file: %v", err)
		}

		if k != 0 {
			// Use fileview to exercise different paths in reader.
			fi, err := os.Stat(mfpath)
			if err != nil {
				t.Fatalf("stat() on meta-file: %v", err)
			}
			fileView = make([]byte, fi.Size())
			if _, err := inf.Read(fileView); err != nil {
				t.Fatalf("read() on meta-file: %v", err)
			}
			if _, err := inf.Seek(int64(0), os.SEEK_SET); err != nil {
				t.Fatalf("seek() on meta-file: %v", err)
			}
		}

		mfr, err := decodemeta.NewCoverageMetaFileReader(inf, fileView)
		if err != nil {
			t.Fatalf("k=%d NewCoverageMetaFileReader failed with: %v", k, err)
		}
		np := mfr.NumPackages()
		if np != 7 {
			t.Fatalf("k=%d wanted 7 packages got %d", k, np)
		}
		md := mfr.CounterMode()
		wmd := coverage.CtrModeAtomic
		if md != wmd {
			t.Fatalf("k=%d wanted mode %d got %d", k, wmd, md)
		}
		gran := mfr.CounterGranularity()
		wgran := coverage.CtrGranularityPerBlock
		if gran != wgran {
			t.Fatalf("k=%d wanted gran %d got %d", k, wgran, gran)
		}

		payload := []byte{}
		for pi := 0; pi < int(np); pi++ {
			var pd *decodemeta.CoverageMetaDataDecoder
			var err error
			pd, payload, err = mfr.GetPackageDecoder(uint32(pi), payload)
			if err != nil {
				t.Fatalf("GetPackageDecoder(%d) failed with: %v", pi, err)
			}
			efuncs := createFuncs(pi)
			nf := pd.NumFuncs()
			if len(efuncs) != int(nf) {
				t.Fatalf("decoding pk %d wanted %d funcs got %d",
					pi, len(efuncs), nf)
			}
			var f coverage.FuncDesc
			for fi := 0; fi < int(nf); fi++ {
				if err := pd.ReadFunc(uint32(fi), &f); err != nil {
					t.Fatalf("ReadFunc(%d) pk %d got error %v",
						fi, pi, err)
				}
				res := cmpFuncDesc(efuncs[fi], f)
				if res != "" {
					t.Errorf("ReadFunc(%d) pk %d: %s", fi, pi, res)
				}
			}
		}
		inf.Close()
	}
}
