// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package tfdiags

import "fmt"

// ConsolidateWarnings checks if there is an unreasonable amount of warnings
// with the same summary in the receiver and, if so, returns a new diagnostics
// with some of those warnings consolidated into a single warning in order
// to reduce the verbosity of the output.
//
// This mechanism is here primarily for diagnostics printed out at the CLI. In
// other contexts it is likely better to just return the warnings directly,
// particularly if they are going to be interpreted by software rather than
// by a human reader.
//
// The returned slice always has a separate backing array from the reciever,
// but some diagnostic values themselves might be shared.
//
// The definition of "unreasonable" is given as the threshold argument. At most
// that many warnings with the same summary will be shown.
func (diags Diagnostics) ConsolidateWarnings(threshold int) Diagnostics {
	if len(diags) == 0 {
		return nil
	}

	newDiags := make(Diagnostics, 0, len(diags))

	// We'll track how many times we've seen each warning summary so we can
	// decide when to start consolidating. Once we _have_ started consolidating,
	// we'll also track the object representing the consolidated warning
	// so we can continue appending to it.
	warningStats := make(map[string]int)
	warningGroups := make(map[string]*warningGroup)

	for _, diag := range diags {
		severity := diag.Severity()
		if severity != Warning || diag.Source().Subject == nil {
			// Only warnings can get special treatment, and we only
			// consolidate warnings that have source locations because
			// our primary goal here is to deal with the situation where
			// some configuration language feature is producing a warning
			// each time it's used across a potentially-large config.
			newDiags = newDiags.Append(diag)
			continue
		}

		if DoNotConsolidateDiagnostic(diag) {
			// Then do not consolidate this diagnostic.
			newDiags = newDiags.Append(diag)
			continue
		}

		desc := diag.Description()
		summary := desc.Summary
		if g, ok := warningGroups[summary]; ok {
			// We're already grouping this one, so we'll just continue it.
			g.Append(diag)
			continue
		}

		warningStats[summary]++
		if warningStats[summary] == threshold {
			// Initially creating the group doesn't really change anything
			// visibly in the result, since a group with only one warning
			// is just a passthrough anyway, but once we do this any additional
			// warnings with the same summary will get appended to this group.
			g := &warningGroup{}
			newDiags = newDiags.Append(g)
			warningGroups[summary] = g
			g.Append(diag)
			continue
		}

		// If this warning is not consolidating yet then we'll just append
		// it directly.
		newDiags = newDiags.Append(diag)
	}

	return newDiags
}

// A warningGroup is one or more warning diagnostics grouped together for
// UI consolidation purposes.
//
// A warningGroup with only one diagnostic in it is just a passthrough for
// that one diagnostic. If it has more than one then it will behave mostly
// like the first one but its detail message will include an additional
// sentence mentioning the consolidation. A warningGroup with no diagnostics
// at all is invalid and will panic when used.
type warningGroup struct {
	Warnings Diagnostics
}

var _ Diagnostic = (*warningGroup)(nil)

func (wg *warningGroup) Severity() Severity {
	return wg.Warnings[0].Severity()
}

func (wg *warningGroup) Description() Description {
	desc := wg.Warnings[0].Description()
	if len(wg.Warnings) < 2 {
		return desc
	}
	extraCount := len(wg.Warnings) - 1
	var msg string
	switch extraCount {
	case 1:
		msg = "(and one more similar warning elsewhere)"
	default:
		msg = fmt.Sprintf("(and %d more similar warnings elsewhere)", extraCount)
	}
	if desc.Detail != "" {
		desc.Detail = desc.Detail + "\n\n" + msg
	} else {
		desc.Detail = msg
	}
	return desc
}

func (wg *warningGroup) Source() Source {
	return wg.Warnings[0].Source()
}

func (wg *warningGroup) FromExpr() *FromExpr {
	return wg.Warnings[0].FromExpr()
}

func (wg *warningGroup) ExtraInfo() interface{} {
	return wg.Warnings[0].ExtraInfo()
}

func (wg *warningGroup) Append(diag Diagnostic) {
	if diag.Severity() != Warning {
		panic("can't append a non-warning diagnostic to a warningGroup")
	}
	wg.Warnings = append(wg.Warnings, diag)
}

// WarningGroupSourceRanges can be used in conjunction with
// Diagnostics.ConsolidateWarnings to recover the full set of original source
// locations from a consolidated warning.
//
// For convenience, this function accepts any diagnostic and will just return
// the single Source value from any diagnostic that isn't a warning group.
func WarningGroupSourceRanges(diag Diagnostic) []Source {
	wg, ok := diag.(*warningGroup)
	if !ok {
		return []Source{diag.Source()}
	}

	ret := make([]Source, len(wg.Warnings))
	for i, wrappedDiag := range wg.Warnings {
		ret[i] = wrappedDiag.Source()
	}
	return ret
}
