// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package checks

import (
	"fmt"
	"sort"
	"sync"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/configs"
)

// State is a container for state tracking of all of the the checks declared in
// a particular Terraform configuration and their current statuses.
//
// A State object is mutable during plan and apply operations but should
// otherwise be treated as a read-only snapshot of the status of checks
// at a particular moment.
//
// The checks State tracks a few different concepts:
//   - configuration objects: items in the configuration which statically
//     declare some checks associated with zero or more checkable objects.
//   - checkable objects: dynamically-determined objects that are each
//     associated with one configuration object.
//   - checks: a single check that is declared as part of a configuration
//     object and then resolved once for each of its associated checkable
//     objects.
//   - check statuses: the current state of a particular check associated
//     with a particular checkable object.
//
// This container type is concurrency-safe for both reads and writes through
// its various methods.
type State struct {
	mu sync.Mutex

	statuses    addrs.Map[addrs.ConfigCheckable, *configCheckableState]
	failureMsgs addrs.Map[addrs.CheckRule, string]
}

// configCheckableState is an internal part of type State that represents
// the evaluation status for a particular addrs.ConfigCheckable address.
//
// Its initial state, at the beginning of a run, is that it doesn't even know
// how many checkable objects will be dynamically-declared yet. Terraform Core
// will notify the State object of the associated Checkables once
// it has decided the appropriate expansion of that configuration object,
// and then will gradually report the results of each check once the graph
// walk reaches it.
//
// This must be accessed only while holding the mutex inside the associated
// State object.
type configCheckableState struct {
	// checkTypes captures the expected number of checks of each type
	// associated with object declared by this configuration construct. Since
	// checks are statically declared (even though the checkable objects
	// aren't) we can compute this only from the configuration.
	checkTypes map[addrs.CheckRuleType]int

	// objects represents the set of dynamic checkable objects associated
	// with this configuration construct. This is initially nil to represent
	// that we don't know the objects yet, and is replaced by a non-nil map
	// once Terraform Core reports the expansion of this configuration
	// construct.
	//
	// The leaf Status values will initially be StatusUnknown
	// and then gradually updated by Terraform Core as it visits the
	// individual checkable objects and reports their status.
	objects addrs.Map[addrs.Checkable, map[addrs.CheckRuleType][]Status]
}

// NOTE: For the "Report"-prefixed methods that we use to gradually update
// the structure with results during a plan or apply operation, see the
// state_report.go file also in this package.

// NewState returns a new State object representing the check statuses of
// objects declared in the given configuration.
//
// The configuration determines which configuration objects and associated
// checks we'll be expecting to see, so that we can seed their statuses as
// all unknown until we see affirmative reports sent by the Report-prefixed
// methods on Checks.
func NewState(config *configs.Config) *State {
	return &State{
		statuses: initialStatuses(config),
	}
}

// ConfigHasChecks returns true if and only if the given address refers to
// a configuration object that this State object is expecting to recieve
// statuses for.
//
// Other methods of Checks will typically panic if given a config address
// that would not have returned true from ConfigHasChecked.
func (c *State) ConfigHasChecks(addr addrs.ConfigCheckable) bool {
	c.mu.Lock()
	defer c.mu.Unlock()
	return c.statuses.Has(addr)
}

// AllConfigAddrs returns all of the addresses of all configuration objects
// that could potentially produce checkable objects at runtime.
//
// This is a good starting point for reporting on the outcome of all of the
// configured checks at the configuration level of granularity, e.g. for
// automated testing reports where we want to report the status of all
// configured checks even if the graph walk aborted before we reached any
// of their objects.
func (c *State) AllConfigAddrs() addrs.Set[addrs.ConfigCheckable] {
	c.mu.Lock()
	defer c.mu.Unlock()
	return c.statuses.Keys()
}

// ObjectAddrs returns the addresses of individual checkable objects belonging
// to the configuration object with the given address.
//
// This will panic if the given address isn't a known configuration object
// that has checks.
func (c *State) ObjectAddrs(configAddr addrs.ConfigCheckable) addrs.Set[addrs.Checkable] {
	c.mu.Lock()
	defer c.mu.Unlock()

	st, ok := c.statuses.GetOk(configAddr)
	if !ok {
		panic(fmt.Sprintf("unknown configuration object %s", configAddr))
	}

	ret := addrs.MakeSet[addrs.Checkable]()
	for _, elem := range st.objects.Elems {
		ret.Add(elem.Key)
	}
	return ret

}

// AggregateCheckStatus returns a summarization of all of the check results
// for a particular configuration object into a single status.
//
// The given address must refer to an object within the configuration that
// this Checks was instantiated from, or this method will panic.
func (c *State) AggregateCheckStatus(addr addrs.ConfigCheckable) Status {
	c.mu.Lock()
	defer c.mu.Unlock()

	st, ok := c.statuses.GetOk(addr)
	if !ok {
		panic(fmt.Sprintf("request for status of unknown configuration object %s", addr))
	}

	if st.objects.Elems == nil {
		// If we don't even know how many objects we have for this
		// configuration construct then that summarizes as unknown.
		// (Note: this is different than Elems being a non-nil empty map,
		// which means that we know there are zero objects and therefore
		// the aggregate result will be pass to pass below.)
		return StatusUnknown
	}

	// Otherwise, our result depends on how many of our known objects are
	// in each status.
	errorCount := 0
	failCount := 0
	unknownCount := 0

	for _, objects := range st.objects.Elems {
		for _, checks := range objects.Value {
			for _, status := range checks {
				switch status {
				case StatusPass:
					// ok
				case StatusFail:
					failCount++
				case StatusError:
					errorCount++
				default:
					unknownCount++
				}
			}
		}
	}

	return summarizeCheckStatuses(errorCount, failCount, unknownCount)
}

// ObjectCheckStatus returns a summarization of all of the check results
// for a particular checkable object into a single status.
//
// The given address must refer to a checkable object that Terraform Core
// previously reported while doing a graph walk, or this method will panic.
func (c *State) ObjectCheckStatus(addr addrs.Checkable) Status {
	c.mu.Lock()
	defer c.mu.Unlock()

	configAddr := addr.ConfigCheckable()

	st, ok := c.statuses.GetOk(configAddr)
	if !ok {
		panic(fmt.Sprintf("request for status of unknown object %s", addr))
	}
	if st.objects.Elems == nil {
		panic(fmt.Sprintf("request for status of %s before establishing the checkable objects for %s", addr, configAddr))
	}
	checks, ok := st.objects.GetOk(addr)
	if !ok {
		panic(fmt.Sprintf("request for status of unknown object %s", addr))
	}

	errorCount := 0
	failCount := 0
	unknownCount := 0
	for _, statuses := range checks {
		for _, status := range statuses {
			switch status {
			case StatusPass:
				// ok
			case StatusFail:
				failCount++
			case StatusError:
				errorCount++
			default:
				unknownCount++
			}
		}
	}
	return summarizeCheckStatuses(errorCount, failCount, unknownCount)
}

// ObjectFailureMessages returns the zero or more failure messages reported
// for the object with the given address.
//
// Failure messages are recorded only for checks whose status is StatusFail,
// but since this aggregates together the results of all of the checks
// on the given object it's possible for there to be a mixture of failures
// and errors at the same time, which would aggregate as StatusError in
// ObjectCheckStatus's result because errors are defined as "stronger"
// than failures.
func (c *State) ObjectFailureMessages(addr addrs.Checkable) []string {
	var ret []string

	configAddr := addr.ConfigCheckable()

	st, ok := c.statuses.GetOk(configAddr)
	if !ok {
		panic(fmt.Sprintf("request for status of unknown object %s", addr))
	}
	if st.objects.Elems == nil {
		panic(fmt.Sprintf("request for status of %s before establishing the checkable objects for %s", addr, configAddr))
	}
	checksByType, ok := st.objects.GetOk(addr)
	if !ok {
		panic(fmt.Sprintf("request for status of unknown object %s", addr))
	}

	for checkType, checks := range checksByType {
		for i, status := range checks {
			if status == StatusFail {
				checkAddr := addrs.NewCheckRule(addr, checkType, i)
				msg := c.failureMsgs.Get(checkAddr)
				if msg != "" {
					ret = append(ret, msg)
				}
			}
		}
	}

	// We always return the messages in a lexical sort order just so that
	// it'll be consistent between runs if we still have the same problems.
	sort.Strings(ret)

	return ret
}

func summarizeCheckStatuses(errorCount, failCount, unknownCount int) Status {
	switch {
	case errorCount > 0:
		// If we saw any errors then we'll treat the whole thing as errored.
		return StatusError
	case failCount > 0:
		// If anything failed then this whole configuration construct failed.
		return StatusFail
	case unknownCount > 0:
		// If nothing failed but we still have unknowns then our outcome isn't
		// known yet.
		return StatusUnknown
	default:
		// If we have no failures and no unknowns then either we have all
		// passes or no checkable objects at all, both of which summarize as
		// a pass.
		return StatusPass
	}
}
