// 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/decodecounter"
	"internal/coverage/encodecounter"
	"io"
	"os"
	"path/filepath"
	"testing"
)

type ctrVis struct {
	funcs []decodecounter.FuncPayload
}

func (v *ctrVis) NumFuncs() (int, error) {
	return len(v.funcs), nil
}

func (v *ctrVis) VisitFuncs(f encodecounter.CounterVisitorFn) error {
	for _, fn := range v.funcs {
		if err := f(fn.PkgIdx, fn.FuncIdx, fn.Counters); err != nil {
			return err
		}
	}
	return nil
}

func mkfunc(p uint32, f uint32, c []uint32) decodecounter.FuncPayload {
	return decodecounter.FuncPayload{
		PkgIdx:   p,
		FuncIdx:  f,
		Counters: c,
	}
}

func TestCounterDataWriterReader(t *testing.T) {
	flavors := []coverage.CounterFlavor{
		coverage.CtrRaw,
		coverage.CtrULeb128,
	}

	isDead := func(fp decodecounter.FuncPayload) bool {
		for _, v := range fp.Counters {
			if v != 0 {
				return false
			}
		}
		return true
	}

	funcs := []decodecounter.FuncPayload{
		mkfunc(0, 0, []uint32{13, 14, 15}),
		mkfunc(0, 1, []uint32{16, 17}),
		mkfunc(1, 0, []uint32{18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 976543, 7}),
	}
	writeVisitor := &ctrVis{funcs: funcs}

	for kf, flav := range flavors {

		t.Logf("testing flavor %d\n", flav)

		// Open a counter data file in preparation for emitting data.
		d := t.TempDir()
		cfpath := filepath.Join(d, fmt.Sprintf("covcounters.hash.0.%d", kf))
		of, err := os.OpenFile(cfpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
		if err != nil {
			t.Fatalf("opening covcounters: %v", err)
		}

		// Perform the encode and write.
		cdfw := encodecounter.NewCoverageDataWriter(of, flav)
		if cdfw == nil {
			t.Fatalf("NewCoverageDataWriter failed")
		}
		finalHash := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0}
		args := map[string]string{"argc": "3", "argv0": "arg0", "argv1": "arg1", "argv2": "arg_________2"}
		if err := cdfw.Write(finalHash, args, writeVisitor); err != nil {
			t.Fatalf("counter file Write failed: %v", err)
		}
		if err := of.Close(); err != nil {
			t.Fatalf("closing covcounters: %v", err)
		}
		cdfw = nil

		// Decode the same file.
		var cdr *decodecounter.CounterDataReader
		inf, err := os.Open(cfpath)
		defer func() {
			if err := inf.Close(); err != nil {
				t.Fatalf("close failed with: %v", err)
			}
		}()

		if err != nil {
			t.Fatalf("reopening covcounters file: %v", err)
		}
		if cdr, err = decodecounter.NewCounterDataReader(cfpath, inf); err != nil {
			t.Fatalf("opening covcounters for read: %v", err)
		}
		decodedArgs := cdr.OsArgs()
		aWant := "[arg0 arg1 arg_________2]"
		aGot := fmt.Sprintf("%+v", decodedArgs)
		if aWant != aGot {
			t.Errorf("reading decoded args, got %s want %s", aGot, aWant)
		}
		for i := range funcs {
			if isDead(funcs[i]) {
				continue
			}
			var fp decodecounter.FuncPayload
			if ok, err := cdr.NextFunc(&fp); err != nil {
				t.Fatalf("reading func %d: %v", i, err)
			} else if !ok {
				t.Fatalf("reading func %d: bad return", i)
			}
			got := fmt.Sprintf("%+v", fp)
			want := fmt.Sprintf("%+v", funcs[i])
			if got != want {
				t.Errorf("cdr.NextFunc iter %d\ngot  %+v\nwant %+v", i, got, want)
			}
		}
		var dummy decodecounter.FuncPayload
		if ok, err := cdr.NextFunc(&dummy); err != nil {
			t.Fatalf("reading func after loop: %v", err)
		} else if ok {
			t.Fatalf("reading func after loop: expected EOF")
		}
	}
}

func TestCounterDataAppendSegment(t *testing.T) {
	d := t.TempDir()
	cfpath := filepath.Join(d, "covcounters.hash2.0")
	of, err := os.OpenFile(cfpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
	if err != nil {
		t.Fatalf("opening covcounters: %v", err)
	}

	const numSegments = 2

	// Write a counter with with multiple segments.
	args := map[string]string{"argc": "1", "argv0": "prog.exe"}
	allfuncs := [][]decodecounter.FuncPayload{}
	ctrs := []uint32{}
	q := uint32(0)
	var cdfw *encodecounter.CoverageDataWriter
	for idx := 0; idx < numSegments; idx++ {
		args[fmt.Sprintf("seg%d", idx)] = "x"
		q += 7
		ctrs = append(ctrs, q)
		funcs := []decodecounter.FuncPayload{}
		for k := 0; k < idx+1; k++ {
			c := make([]uint32, len(ctrs))
			copy(c, ctrs)
			funcs = append(funcs, mkfunc(uint32(idx), uint32(k), c))
		}
		allfuncs = append(allfuncs, funcs)

		writeVisitor := &ctrVis{funcs: funcs}

		if idx == 0 {
			// Perform the encode and write.
			cdfw = encodecounter.NewCoverageDataWriter(of, coverage.CtrRaw)
			if cdfw == nil {
				t.Fatalf("NewCoverageDataWriter failed")
			}
			finalHash := [16]byte{1, 2}
			if err := cdfw.Write(finalHash, args, writeVisitor); err != nil {
				t.Fatalf("counter file Write failed: %v", err)
			}
		} else {
			if err := cdfw.AppendSegment(args, writeVisitor); err != nil {
				t.Fatalf("counter file AppendSegment failed: %v", err)
			}
		}
	}
	if err := of.Close(); err != nil {
		t.Fatalf("closing covcounters: %v", err)
	}

	// Read the result file.
	var cdr *decodecounter.CounterDataReader
	inf, err := os.Open(cfpath)
	defer func() {
		if err := inf.Close(); err != nil {
			t.Fatalf("close failed with: %v", err)
		}
	}()

	if err != nil {
		t.Fatalf("reopening covcounters file: %v", err)
	}
	if cdr, err = decodecounter.NewCounterDataReader(cfpath, inf); err != nil {
		t.Fatalf("opening covcounters for read: %v", err)
	}
	ns := cdr.NumSegments()
	if ns != numSegments {
		t.Fatalf("got %d segments want %d", ns, numSegments)
	}
	if len(allfuncs) != numSegments {
		t.Fatalf("expected %d got %d", numSegments, len(allfuncs))
	}

	for sidx := 0; sidx < int(ns); sidx++ {
		if off, err := inf.Seek(0, io.SeekCurrent); err != nil {
			t.Fatalf("Seek failed: %v", err)
		} else {
			t.Logf("sidx=%d off=%d\n", sidx, off)
		}

		if sidx != 0 {
			if ok, err := cdr.BeginNextSegment(); err != nil {
				t.Fatalf("BeginNextSegment failed: %v", err)
			} else if !ok {
				t.Fatalf("BeginNextSegment return %v on iter %d",
					ok, sidx)
			}
		}
		funcs := allfuncs[sidx]
		for i := range funcs {
			var fp decodecounter.FuncPayload
			if ok, err := cdr.NextFunc(&fp); err != nil {
				t.Fatalf("reading func %d: %v", i, err)
			} else if !ok {
				t.Fatalf("reading func %d: bad return", i)
			}
			got := fmt.Sprintf("%+v", fp)
			want := fmt.Sprintf("%+v", funcs[i])
			if got != want {
				t.Errorf("cdr.NextFunc iter %d\ngot  %+v\nwant %+v", i, got, want)
			}
		}
	}
}
