// 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"
	"io"
	"sync/atomic"
	"unsafe"
)

// WriteMetaDir writes a coverage meta-data file for the currently
// running program to the directory specified in 'dir'. An error will
// be returned if the operation can't be completed successfully (for
// example, if the currently running program was not built with
// "-cover", or if the directory does not exist).
func WriteMetaDir(dir string) error {
	if !finalHashComputed {
		return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
	}
	return emitMetaDataToDirectory(dir, getCovMetaList())
}

// WriteMeta writes the meta-data content (the payload that would
// normally be emitted to a meta-data file) for the currently running
// program to the writer 'w'. An error will be returned if the
// operation can't be completed successfully (for example, if the
// currently running program was not built with "-cover", or if a
// write fails).
func WriteMeta(w io.Writer) error {
	if w == nil {
		return fmt.Errorf("error: nil writer in WriteMeta")
	}
	if !finalHashComputed {
		return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
	}
	ml := getCovMetaList()
	return writeMetaData(w, ml, cmode, cgran, finalHash)
}

// WriteCountersDir writes a coverage counter-data file for the
// currently running program to the directory specified in 'dir'. An
// error will be returned if the operation can't be completed
// successfully (for example, if the currently running program was not
// built with "-cover", or if the directory does not exist). The
// counter data written will be a snapshot taken at the point of the
// call.
func WriteCountersDir(dir string) error {
	if cmode != coverage.CtrModeAtomic {
		return fmt.Errorf("WriteCountersDir invoked for program built with -covermode=%s (please use -covermode=atomic)", cmode.String())
	}
	return emitCounterDataToDirectory(dir)
}

// WriteCounters writes coverage counter-data content for the
// currently running program to the writer 'w'. An error will be
// returned if the operation can't be completed successfully (for
// example, if the currently running program was not built with
// "-cover", or if a write fails). The counter data written will be a
// snapshot taken at the point of the invocation.
func WriteCounters(w io.Writer) error {
	if w == nil {
		return fmt.Errorf("error: nil writer in WriteCounters")
	}
	if cmode != coverage.CtrModeAtomic {
		return fmt.Errorf("WriteCounters invoked for program built with -covermode=%s (please use -covermode=atomic)", cmode.String())
	}
	// Ask the runtime for the list of coverage counter symbols.
	cl := getCovCounterList()
	if len(cl) == 0 {
		return fmt.Errorf("program not built with -cover")
	}
	if !finalHashComputed {
		return fmt.Errorf("meta-data not written yet, unable to write counter data")
	}

	pm := getCovPkgMap()
	s := &emitState{
		counterlist: cl,
		pkgmap:      pm,
	}
	return s.emitCounterDataToWriter(w)
}

// ClearCounters clears/resets all coverage counter variables in the
// currently running program. It returns an error if the program in
// question was not built with the "-cover" flag. Clearing of coverage
// counters is also not supported for programs not using atomic
// counter mode (see more detailed comments below for the rationale
// here).
func ClearCounters() error {
	cl := getCovCounterList()
	if len(cl) == 0 {
		return fmt.Errorf("program not built with -cover")
	}
	if cmode != coverage.CtrModeAtomic {
		return fmt.Errorf("ClearCounters invoked for program built with -covermode=%s (please use -covermode=atomic)", cmode.String())
	}

	// Implementation note: this function would be faster and simpler
	// if we could just zero out the entire counter array, but for the
	// moment we go through and zero out just the slots in the array
	// corresponding to the counter values. We do this to avoid the
	// following bad scenario: suppose that a user builds their Go
	// program with "-cover", and that program has a function (call it
	// main.XYZ) that invokes ClearCounters:
	//
	//     func XYZ() {
	//       ... do some stuff ...
	//       coverage.ClearCounters()
	//       if someCondition {   <<--- HERE
	//         ...
	//       }
	//     }
	//
	// At the point where ClearCounters executes, main.XYZ has not yet
	// finished running, thus as soon as the call returns the line
	// marked "HERE" above will trigger the writing of a non-zero
	// value into main.XYZ's counter slab. However since we've just
	// finished clearing the entire counter segment, we will have lost
	// the values in the prolog portion of main.XYZ's counter slab
	// (nctrs, pkgid, funcid). This means that later on at the end of
	// program execution as we walk through the entire counter array
	// for the program looking for executed functions, we'll zoom past
	// main.XYZ's prolog (which was zero'd) and hit the non-zero
	// counter value corresponding to the "HERE" block, which will
	// then be interpreted as the start of another live function.
	// Things will go downhill from there.
	//
	// This same scenario is also a potential risk if the program is
	// running on an architecture that permits reordering of
	// writes/stores, since the inconsistency described above could
	// arise here. Example scenario:
	//
	//     func ABC() {
	//       ...                    // prolog
	//       if alwaysTrue() {
	//         XYZ()                // counter update here
	//       }
	//     }
	//
	// In the instrumented version of ABC, the prolog of the function
	// will contain a series of stores to the initial portion of the
	// counter array to write number-of-counters, pkgid, funcid. Later
	// in the function there is also a store to increment a counter
	// for the block containing the call to XYZ(). If the CPU is
	// allowed to reorder stores and decides to issue the XYZ store
	// before the prolog stores, this could be observable as an
	// inconsistency similar to the one above. Hence the requirement
	// for atomic counter mode: according to package atomic docs,
	// "...operations that happen in a specific order on one thread,
	// will always be observed to happen in exactly that order by
	// another thread". Thus we can be sure that there will be no
	// inconsistency when reading the counter array from the thread
	// running ClearCounters.

	for _, c := range cl {
		sd := unsafe.Slice((*atomic.Uint32)(unsafe.Pointer(c.Counters)), int(c.Len))
		for i := 0; i < len(sd); i++ {
			// Skip ahead until the next non-zero value.
			sdi := sd[i].Load()
			if sdi == 0 {
				continue
			}
			// We found a function that was executed; clear its counters.
			nCtrs := sdi
			for j := 0; j < int(nCtrs); j++ {
				sd[i+coverage.FirstCtrOffset+j].Store(0)
			}
			// Move to next function.
			i += coverage.FirstCtrOffset + int(nCtrs) - 1
		}
	}
	return nil
}
