package discovery

// A PluginMetaSet is a set of PluginMeta objects meeting a certain criteria.
//
// Methods on this type allow filtering of the set to produce subsets that
// meet more restrictive criteria.
type PluginMetaSet map[PluginMeta]struct{}

// Add inserts the given PluginMeta into the receiving set. This is a no-op
// if the given meta is already present.
func (s PluginMetaSet) Add(p PluginMeta) {
	s[p] = struct{}{}
}

// Remove removes the given PluginMeta from the receiving set. This is a no-op
// if the given meta is not already present.
func (s PluginMetaSet) Remove(p PluginMeta) {
	delete(s, p)
}

// Has returns true if the given meta is in the receiving set, or false
// otherwise.
func (s PluginMetaSet) Has(p PluginMeta) bool {
	_, ok := s[p]
	return ok
}

// Count returns the number of metas in the set
func (s PluginMetaSet) Count() int {
	return len(s)
}

// ValidateVersions returns two new PluginMetaSets, separating those with
// versions that have syntax-valid semver versions from those that don't.
//
// Eliminating invalid versions from consideration (and possibly warning about
// them) is usually the first step of working with a meta set after discovery
// has completed.
func (s PluginMetaSet) ValidateVersions() (valid, invalid PluginMetaSet) {
	valid = make(PluginMetaSet)
	invalid = make(PluginMetaSet)
	for p := range s {
		if _, err := p.Version.Parse(); err == nil {
			valid.Add(p)
		} else {
			invalid.Add(p)
		}
	}
	return
}

// WithName returns the subset of metas that have the given name.
func (s PluginMetaSet) WithName(name string) PluginMetaSet {
	ns := make(PluginMetaSet)
	for p := range s {
		if p.Name == name {
			ns.Add(p)
		}
	}
	return ns
}

// WithVersion returns the subset of metas that have the given version.
//
// This should be used only with the "valid" result from ValidateVersions;
// it will ignore any plugin metas that have invalid version strings.
func (s PluginMetaSet) WithVersion(version Version) PluginMetaSet {
	ns := make(PluginMetaSet)
	for p := range s {
		gotVersion, err := p.Version.Parse()
		if err != nil {
			continue
		}
		if gotVersion.Equal(version) {
			ns.Add(p)
		}
	}
	return ns
}

// ByName groups the metas in the set by their Names, returning a map.
func (s PluginMetaSet) ByName() map[string]PluginMetaSet {
	ret := make(map[string]PluginMetaSet)
	for p := range s {
		if _, ok := ret[p.Name]; !ok {
			ret[p.Name] = make(PluginMetaSet)
		}
		ret[p.Name].Add(p)
	}
	return ret
}

// Newest returns the one item from the set that has the newest Version value.
//
// The result is meaningful only if the set is already filtered such that
// all of the metas have the same Name.
//
// If there isn't at least one meta in the set then this function will panic.
// Use Count() to ensure that there is at least one value before calling.
//
// If any of the metas have invalid version strings then this function will
// panic. Use ValidateVersions() first to filter out metas with invalid
// versions.
//
// If two metas have the same Version then one is arbitrarily chosen. This
// situation should be avoided by pre-filtering the set.
func (s PluginMetaSet) Newest() PluginMeta {
	if len(s) == 0 {
		panic("can't call NewestStable on empty PluginMetaSet")
	}

	var first = true
	var winner PluginMeta
	var winnerVersion Version
	for p := range s {
		version, err := p.Version.Parse()
		if err != nil {
			panic(err)
		}

		if first || version.NewerThan(winnerVersion) {
			winner = p
			winnerVersion = version
			first = false
		}
	}

	return winner
}

// ConstrainVersions takes a set of requirements and attempts to
// return a map from name to a set of metas that have the matching
// name and an appropriate version.
//
// If any of the given requirements match *no* plugins then its PluginMetaSet
// in the returned map will be empty.
//
// All viable metas are returned, so the caller can apply any desired filtering
// to reduce down to a single option. For example, calling Newest() to obtain
// the highest available version.
//
// If any of the metas in the set have invalid version strings then this
// function will panic. Use ValidateVersions() first to filter out metas with
// invalid versions.
func (s PluginMetaSet) ConstrainVersions(reqd PluginRequirements) map[string]PluginMetaSet {
	ret := make(map[string]PluginMetaSet)
	for p := range s {
		name := p.Name
		allowedVersions, ok := reqd[name]
		if !ok {
			continue
		}
		if _, ok := ret[p.Name]; !ok {
			ret[p.Name] = make(PluginMetaSet)
		}
		version, err := p.Version.Parse()
		if err != nil {
			panic(err)
		}
		if allowedVersions.Allows(version) {
			ret[p.Name].Add(p)
		}
	}
	return ret
}

// OverridePaths returns a new set where any existing plugins with the given
// names are removed and replaced with the single path given in the map.
//
// This is here only to continue to support the legacy way of overriding
// plugin binaries in the .terraformrc file. It treats all given plugins
// as pre-versioning (version 0.0.0). This mechanism will eventually be
// phased out, with vendor directories being the intended replacement.
func (s PluginMetaSet) OverridePaths(paths map[string]string) PluginMetaSet {
	ret := make(PluginMetaSet)
	for p := range s {
		if _, ok := paths[p.Name]; ok {
			// Skip plugins that we're overridding
			continue
		}

		ret.Add(p)
	}

	// Now add the metadata for overriding plugins
	for name, path := range paths {
		ret.Add(PluginMeta{
			Name:    name,
			Version: VersionZero,
			Path:    path,
		})
	}

	return ret
}
