// Copyright 2022 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 coverage

import (
	"fmt"
	"internal/coverage"
	"internal/coverage/calloc"
	"internal/coverage/cformat"
	"internal/coverage/cmerge"
	"internal/coverage/decodecounter"
	"internal/coverage/decodemeta"
	"internal/coverage/pods"
	"io"
	"os"
)

// processCoverTestDir is called (via a linknamed reference) from
// testmain code when "go test -cover" is in effect. It is not
// intended to be used other than internally by the Go command's
// generated code.
func processCoverTestDir(dir string, cfile string, cm string, cpkg string) error {
	return processCoverTestDirInternal(dir, cfile, cm, cpkg, os.Stdout)
}

// processCoverTestDirInternal is an io.Writer version of processCoverTestDir,
// exposed for unit testing.
func processCoverTestDirInternal(dir string, cfile string, cm string, cpkg string, w io.Writer) error {
	cmode := coverage.ParseCounterMode(cm)
	if cmode == coverage.CtrModeInvalid {
		return fmt.Errorf("invalid counter mode %q", cm)
	}

	// Emit meta-data and counter data.
	ml := getCovMetaList()
	if len(ml) == 0 {
		// This corresponds to the case where we have a package that
		// contains test code but no functions (which is fine). In this
		// case there is no need to emit anything.
	} else {
		if err := emitMetaDataToDirectory(dir, ml); err != nil {
			return err
		}
		if err := emitCounterDataToDirectory(dir); err != nil {
			return err
		}
	}

	// Collect pods from test run. For the majority of cases we would
	// expect to see a single pod here, but allow for multiple pods in
	// case the test harness is doing extra work to collect data files
	// from builds that it kicks off as part of the testing.
	podlist, err := pods.CollectPods([]string{dir}, false)
	if err != nil {
		return fmt.Errorf("reading from %s: %v", dir, err)
	}

	// Open text output file if appropriate.
	var tf *os.File
	var tfClosed bool
	if cfile != "" {
		var err error
		tf, err = os.Create(cfile)
		if err != nil {
			return fmt.Errorf("internal error: opening coverage data output file %q: %v", cfile, err)
		}
		defer func() {
			if !tfClosed {
				tfClosed = true
				tf.Close()
			}
		}()
	}

	// Read/process the pods.
	ts := &tstate{
		cm:    &cmerge.Merger{},
		cf:    cformat.NewFormatter(cmode),
		cmode: cmode,
	}
	for _, p := range podlist {
		if err := ts.processPod(p); err != nil {
			return err
		}
	}

	// Emit percent.
	if err := ts.cf.EmitPercent(w, cpkg, true); err != nil {
		return err
	}

	// Emit text output.
	if tf != nil {
		if err := ts.cf.EmitTextual(tf); err != nil {
			return err
		}
		tfClosed = true
		if err := tf.Close(); err != nil {
			return fmt.Errorf("closing %s: %v", cfile, err)
		}
	}

	return nil
}

type tstate struct {
	calloc.BatchCounterAlloc
	cm    *cmerge.Merger
	cf    *cformat.Formatter
	cmode coverage.CounterMode
}

// processPod reads coverage counter data for a specific pod.
func (ts *tstate) processPod(p pods.Pod) error {
	// Open meta-data file
	f, err := os.Open(p.MetaFile)
	if err != nil {
		return fmt.Errorf("unable to open meta-data file %s: %v", p.MetaFile, err)
	}
	defer func() {
		f.Close()
	}()
	var mfr *decodemeta.CoverageMetaFileReader
	mfr, err = decodemeta.NewCoverageMetaFileReader(f, nil)
	if err != nil {
		return fmt.Errorf("error reading meta-data file %s: %v", p.MetaFile, err)
	}
	newmode := mfr.CounterMode()
	if newmode != ts.cmode {
		return fmt.Errorf("internal error: counter mode clash: %q from test harness, %q from data file %s", ts.cmode.String(), newmode.String(), p.MetaFile)
	}
	newgran := mfr.CounterGranularity()
	if err := ts.cm.SetModeAndGranularity(p.MetaFile, cmode, newgran); err != nil {
		return err
	}

	// Read counter data files.
	pmm := make(map[pkfunc][]uint32)
	for _, cdf := range p.CounterDataFiles {
		cf, err := os.Open(cdf)
		if err != nil {
			return fmt.Errorf("opening counter data file %s: %s", cdf, err)
		}
		var cdr *decodecounter.CounterDataReader
		cdr, err = decodecounter.NewCounterDataReader(cdf, cf)
		if err != nil {
			return fmt.Errorf("reading counter data file %s: %s", cdf, err)
		}
		var data decodecounter.FuncPayload
		for {
			ok, err := cdr.NextFunc(&data)
			if err != nil {
				return fmt.Errorf("reading counter data file %s: %v", cdf, err)
			}
			if !ok {
				break
			}

			// NB: sanity check on pkg and func IDs?
			key := pkfunc{pk: data.PkgIdx, fcn: data.FuncIdx}
			if prev, found := pmm[key]; found {
				// Note: no overflow reporting here.
				if err, _ := ts.cm.MergeCounters(data.Counters, prev); err != nil {
					return fmt.Errorf("processing counter data file %s: %v", cdf, err)
				}
			}
			c := ts.AllocateCounters(len(data.Counters))
			copy(c, data.Counters)
			pmm[key] = c
		}
	}

	// Visit meta-data file.
	np := uint32(mfr.NumPackages())
	payload := []byte{}
	for pkIdx := uint32(0); pkIdx < np; pkIdx++ {
		var pd *decodemeta.CoverageMetaDataDecoder
		pd, payload, err = mfr.GetPackageDecoder(pkIdx, payload)
		if err != nil {
			return fmt.Errorf("reading pkg %d from meta-file %s: %s", pkIdx, p.MetaFile, err)
		}
		ts.cf.SetPackage(pd.PackagePath())
		var fd coverage.FuncDesc
		nf := pd.NumFuncs()
		for fnIdx := uint32(0); fnIdx < nf; fnIdx++ {
			if err := pd.ReadFunc(fnIdx, &fd); err != nil {
				return fmt.Errorf("reading meta-data file %s: %v",
					p.MetaFile, err)
			}
			key := pkfunc{pk: pkIdx, fcn: fnIdx}
			counters, haveCounters := pmm[key]
			for i := 0; i < len(fd.Units); i++ {
				u := fd.Units[i]
				// Skip units with non-zero parent (no way to represent
				// these in the existing format).
				if u.Parent != 0 {
					continue
				}
				count := uint32(0)
				if haveCounters {
					count = counters[i]
				}
				ts.cf.AddUnit(fd.Srcfile, fd.Funcname, fd.Lit, u, count)
			}
		}
	}
	return nil
}

type pkfunc struct {
	pk, fcn uint32
}
