package attribute_path

import "encoding/json"

// Matcher provides an interface for stepping through changes following an
// attribute path.
//
// GetChildWithKey and GetChildWithIndex will check if any of the internal paths
// match the provided key or index, and return a new Matcher that will match
// that children or potentially it's children.
//
// The caller of the above functions is required to know whether the next value
// in the path is a list type or an object type and call the relevant function,
// otherwise these functions will crash/panic.
//
// The Matches function returns true if the paths you have traversed until now
// ends.
type Matcher interface {
	// Matches returns true if we have reached the end of a path and found an
	// exact match.
	Matches() bool

	// MatchesPartial returns true if the current attribute is part of a path
	// but not necessarily at the end of the path.
	MatchesPartial() bool

	GetChildWithKey(key string) Matcher
	GetChildWithIndex(index int) Matcher
}

// Parse accepts a json.RawMessage and outputs a formatted Matcher object.
//
// Parse expects the message to be a JSON array of JSON arrays containing
// strings and floats. This function happily accepts a null input representing
// none of the changes in this resource are causing a replacement. The propagate
// argument tells the matcher to propagate any matches to the matched attributes
// children.
//
// In general, this function is designed to accept messages that have been
// produced by the lossy cty.Paths conversion functions within the jsonplan
// package. There is nothing particularly special about that conversion process
// though, it just produces the nested JSON arrays described above.
func Parse(message json.RawMessage, propagate bool) Matcher {
	matcher := &PathMatcher{
		Propagate: propagate,
	}
	if message == nil {
		return matcher
	}

	if err := json.Unmarshal(message, &matcher.Paths); err != nil {
		panic("failed to unmarshal attribute paths: " + err.Error())
	}

	return matcher
}

// Empty returns an empty PathMatcher that will by default match nothing.
//
// We give direct access to the PathMatcher struct so a matcher can be built
// in parts with the Append and AppendSingle functions.
func Empty(propagate bool) *PathMatcher {
	return &PathMatcher{
		Propagate: propagate,
	}
}

// Append accepts an existing PathMatcher and returns a new one that attaches
// all the paths from message with the existing paths.
//
// The new PathMatcher is created fresh, and the existing one is unchanged.
func Append(matcher *PathMatcher, message json.RawMessage) *PathMatcher {
	var values [][]interface{}
	if err := json.Unmarshal(message, &values); err != nil {
		panic("failed to unmarshal attribute paths: " + err.Error())
	}

	return &PathMatcher{
		Propagate: matcher.Propagate,
		Paths:     append(matcher.Paths, values...),
	}
}

// AppendSingle accepts an existing PathMatcher and returns a new one that
// attaches the single path from message with the existing paths.
//
// The new PathMatcher is created fresh, and the existing one is unchanged.
func AppendSingle(matcher *PathMatcher, message json.RawMessage) *PathMatcher {
	var values []interface{}
	if err := json.Unmarshal(message, &values); err != nil {
		panic("failed to unmarshal attribute paths: " + err.Error())
	}

	return &PathMatcher{
		Propagate: matcher.Propagate,
		Paths:     append(matcher.Paths, values),
	}
}

// PathMatcher contains a slice of paths that represent paths through the values
// to relevant/tracked attributes.
type PathMatcher struct {
	// We represent our internal paths as a [][]interface{} as the cty.Paths
	// conversion process is lossy. Since the type information is lost there
	// is no (easy) way to reproduce the original cty.Paths object. Instead,
	// we simply rely on the external callers to know the type information and
	// call the correct GetChild function.
	Paths [][]interface{}

	// Propagate tells the matcher that it should propagate any matches it finds
	// onto the children of that match.
	Propagate bool
}

func (p *PathMatcher) Matches() bool {
	for _, path := range p.Paths {
		if len(path) == 0 {
			return true
		}
	}
	return false
}

func (p *PathMatcher) MatchesPartial() bool {
	return len(p.Paths) > 0
}

func (p *PathMatcher) GetChildWithKey(key string) Matcher {
	child := &PathMatcher{
		Propagate: p.Propagate,
	}
	for _, path := range p.Paths {
		if len(path) == 0 {
			// This means that the current value matched, but not necessarily
			// it's child.

			if p.Propagate {
				// If propagate is true, then our child match our matches
				child.Paths = append(child.Paths, path)
			}

			// If not we would simply drop this path from our set of paths but
			// either way we just continue.
			continue
		}

		if path[0].(string) == key {
			child.Paths = append(child.Paths, path[1:])
		}
	}
	return child
}

func (p *PathMatcher) GetChildWithIndex(index int) Matcher {
	child := &PathMatcher{
		Propagate: p.Propagate,
	}
	for _, path := range p.Paths {
		if len(path) == 0 {
			// This means that the current value matched, but not necessarily
			// it's child.

			if p.Propagate {
				// If propagate is true, then our child match our matches
				child.Paths = append(child.Paths, path)
			}

			// If not we would simply drop this path from our set of paths but
			// either way we just continue.
			continue
		}

		if int(path[0].(float64)) == index {
			child.Paths = append(child.Paths, path[1:])
		}
	}
	return child
}

// AlwaysMatcher returns a matcher that will always match all paths.
func AlwaysMatcher() Matcher {
	return &alwaysMatcher{}
}

type alwaysMatcher struct{}

func (a *alwaysMatcher) Matches() bool {
	return true
}

func (a *alwaysMatcher) MatchesPartial() bool {
	return true
}

func (a *alwaysMatcher) GetChildWithKey(_ string) Matcher {
	return a
}

func (a *alwaysMatcher) GetChildWithIndex(_ int) Matcher {
	return a
}
