package providercache

import (
	"context"
	"fmt"
	"log"
	"sort"
	"strings"

	"github.com/apparentlymart/go-versions/versions"

	"github.com/hashicorp/terraform/internal/addrs"
	copydir "github.com/hashicorp/terraform/internal/copy"
	"github.com/hashicorp/terraform/internal/depsfile"
	"github.com/hashicorp/terraform/internal/getproviders"
)

// Installer is the main type in this package, representing a provider installer
// with a particular configuration-specific cache directory and an optional
// global cache directory.
type Installer struct {
	// targetDir is the cache directory we're ultimately aiming to get the
	// requested providers installed into.
	targetDir *Dir

	// source is the provider source that the installer will use to discover
	// what provider versions are available for installation and to
	// find the source locations for any versions that are not already
	// available via one of the cache directories.
	source getproviders.Source

	// globalCacheDir is an optional additional directory that will, if
	// provided, be treated as a read-through cache when retrieving new
	// provider versions. That is, new packages are fetched into this
	// directory first and then linked into targetDir, which allows sharing
	// both the disk space and the download time for a particular provider
	// version between different configurations on the same system.
	globalCacheDir *Dir

	// globalCacheDirMayBreakDependencyLockFile allows a temporary exception to
	// the rule that an entry in globalCacheDir can normally only be used if
	// its validity is already confirmed by an entry in the dependency lock
	// file.
	globalCacheDirMayBreakDependencyLockFile bool

	// builtInProviderTypes is an optional set of types that should be
	// considered valid to appear in the special terraform.io/builtin/...
	// namespace, which we use for providers that are built in to Terraform
	// and thus do not need any separate installation step.
	builtInProviderTypes []string

	// unmanagedProviderTypes is a set of provider addresses that should be
	// considered implemented, but that Terraform does not manage the
	// lifecycle for, and therefore does not need to worry about the
	// installation of.
	unmanagedProviderTypes map[addrs.Provider]struct{}
}

// NewInstaller constructs and returns a new installer with the given target
// directory and provider source.
//
// A newly-created installer does not have a global cache directory configured,
// but a caller can make a follow-up call to SetGlobalCacheDir to provide
// one prior to taking any installation actions.
//
// The target directory MUST NOT also be an input consulted by the given source,
// or the result is undefined.
func NewInstaller(targetDir *Dir, source getproviders.Source) *Installer {
	return &Installer{
		targetDir: targetDir,
		source:    source,
	}
}

// Clone returns a new Installer which has the a new target directory but
// the same optional global cache directory, the same installation sources,
// and the same built-in/unmanaged providers. The result can be mutated further
// using the various setter methods without affecting the original.
func (i *Installer) Clone(targetDir *Dir) *Installer {
	// For now all of our setter methods just overwrite field values in
	// their entirety, rather than mutating things on the other side of
	// the shared pointers, and so we can safely just shallow-copy the
	// root. We might need to be more careful here if in future we add
	// methods that allow deeper mutations through the stored pointers.
	ret := *i
	ret.targetDir = targetDir
	return &ret
}

// ProviderSource returns the getproviders.Source that the installer would
// use for installing any new providers.
func (i *Installer) ProviderSource() getproviders.Source {
	return i.source
}

// SetGlobalCacheDir activates a second tier of caching for the receiving
// installer, with the given directory used as a read-through cache for
// installation operations that need to retrieve new packages.
//
// The global cache directory for an installer must never be the same as its
// target directory, and must not be used as one of its provider sources.
// If these overlap then undefined behavior will result.
func (i *Installer) SetGlobalCacheDir(cacheDir *Dir) {
	// A little safety check to catch straightforward mistakes where the
	// directories overlap. Better to panic early than to do
	// possibly-distructive actions on the cache directory downstream.
	if same, err := copydir.SameFile(i.targetDir.baseDir, cacheDir.baseDir); err == nil && same {
		panic(fmt.Sprintf("global cache directory %s must not match the installation target directory %s", cacheDir.baseDir, i.targetDir.baseDir))
	}
	i.globalCacheDir = cacheDir
}

// SetGlobalCacheDirMayBreakDependencyLockFile activates or deactivates our
// temporary exception to the rule that the global cache directory can be used
// only when entries are confirmed by existing entries in the dependency lock
// file.
//
// If this is set then if we install a provider for the first time from the
// cache then the dependency lock file will include only the checksum from
// the package in the global cache, which means the lock file won't be portable
// to Terraform running on another operating system or CPU architecture.
func (i *Installer) SetGlobalCacheDirMayBreakDependencyLockFile(mayBreak bool) {
	i.globalCacheDirMayBreakDependencyLockFile = mayBreak
}

// HasGlobalCacheDir returns true if someone has previously called
// SetGlobalCacheDir to configure a global cache directory for this installer.
func (i *Installer) HasGlobalCacheDir() bool {
	return i.globalCacheDir != nil
}

// SetBuiltInProviderTypes tells the receiver to consider the type names in the
// given slice to be valid as providers in the special special
// terraform.io/builtin/... namespace that we use for providers that are
// built in to Terraform and thus do not need a separate installation step.
//
// If a caller requests installation of a provider in that namespace, the
// installer will treat it as a no-op if its name exists in this list, but
// will produce an error if it does not.
//
// The default, if this method isn't called, is for there to be no valid
// builtin providers.
//
// Do not modify the buffer under the given slice after passing it to this
// method.
func (i *Installer) SetBuiltInProviderTypes(types []string) {
	i.builtInProviderTypes = types
}

// SetUnmanagedProviderTypes tells the receiver to consider the providers
// indicated by the passed addrs.Providers as unmanaged. Terraform does not
// need to control the lifecycle of these providers, and they are assumed to be
// running already when Terraform is started. Because these are essentially
// processes, not binaries, Terraform will not do any work to ensure presence
// or versioning of these binaries.
func (i *Installer) SetUnmanagedProviderTypes(types map[addrs.Provider]struct{}) {
	i.unmanagedProviderTypes = types
}

// EnsureProviderVersions compares the given provider requirements with what
// is already available in the installer's target directory and then takes
// appropriate installation actions to ensure that suitable packages
// are available in the target cache directory.
//
// The given mode modifies how the operation will treat providers that already
// have acceptable versions available in the target cache directory. See the
// documentation for InstallMode and the InstallMode values for more
// information.
//
// The given context can be used to cancel the overall installation operation
// (causing any operations in progress to fail with an error), and can also
// include an InstallerEvents value for optional intermediate progress
// notifications.
//
// If a given InstallerEvents subscribes to notifications about installation
// failures then those notifications will be redundant with the ones included
// in the final returned error value so callers should show either one or the
// other, and not both.
func (i *Installer) EnsureProviderVersions(ctx context.Context, locks *depsfile.Locks, reqs getproviders.Requirements, mode InstallMode) (*depsfile.Locks, error) {
	errs := map[addrs.Provider]error{}
	evts := installerEventsForContext(ctx)

	// We'll work with a copy of the given locks, so we can modify it and
	// return the updated locks without affecting the caller's object.
	// We'll add, replace, or remove locks in here during our work so that the
	// final locks file reflects what the installer has selected.
	locks = locks.DeepCopy()

	if cb := evts.PendingProviders; cb != nil {
		cb(reqs)
	}

	// Step 1: Which providers might we need to fetch a new version of?
	// This produces the subset of requirements we need to ask the provider
	// source about. If we're in the normal (non-upgrade) mode then we'll
	// just ask the source to confirm the continued existence of what
	// was locked, or otherwise we'll find the newest version matching the
	// configured version constraint.
	mightNeed := map[addrs.Provider]getproviders.VersionSet{}
	locked := map[addrs.Provider]bool{}
	for provider, versionConstraints := range reqs {
		if provider.IsBuiltIn() {
			// Built in providers do not require installation but we'll still
			// verify that the requested provider name is valid.
			valid := false
			for _, name := range i.builtInProviderTypes {
				if name == provider.Type {
					valid = true
					break
				}
			}
			var err error
			if valid {
				if len(versionConstraints) == 0 {
					// Other than reporting an event for the outcome of this
					// provider, we'll do nothing else with it: it's just
					// automatically available for use.
					if cb := evts.BuiltInProviderAvailable; cb != nil {
						cb(provider)
					}
				} else {
					// A built-in provider is not permitted to have an explicit
					// version constraint, because we can only use the version
					// that is built in to the current Terraform release.
					err = fmt.Errorf("built-in providers do not support explicit version constraints")
				}
			} else {
				err = fmt.Errorf("this Terraform release has no built-in provider named %q", provider.Type)
			}
			if err != nil {
				errs[provider] = err
				if cb := evts.BuiltInProviderFailure; cb != nil {
					cb(provider, err)
				}
			}
			continue
		}
		if _, ok := i.unmanagedProviderTypes[provider]; ok {
			// unmanaged providers do not require installation
			continue
		}
		acceptableVersions := versions.MeetingConstraints(versionConstraints)
		if !mode.forceQueryAllProviders() {
			// If we're not forcing potential changes of version then an
			// existing selection from the lock file takes priority over
			// the currently-configured version constraints.
			if lock := locks.Provider(provider); lock != nil {
				if !acceptableVersions.Has(lock.Version()) {
					err := fmt.Errorf(
						"locked provider %s %s does not match configured version constraint %s; must use terraform init -upgrade to allow selection of new versions",
						provider, lock.Version(), getproviders.VersionConstraintsString(versionConstraints),
					)
					errs[provider] = err
					// This is a funny case where we're returning an error
					// before we do any querying at all. To keep the event
					// stream consistent without introducing an extra event
					// type, we'll emit an artificial QueryPackagesBegin for
					// this provider before we indicate that it failed using
					// QueryPackagesFailure.
					if cb := evts.QueryPackagesBegin; cb != nil {
						cb(provider, versionConstraints, true)
					}
					if cb := evts.QueryPackagesFailure; cb != nil {
						cb(provider, err)
					}
					continue
				}
				acceptableVersions = versions.Only(lock.Version())
				locked[provider] = true
			}
		}
		mightNeed[provider] = acceptableVersions
	}

	// Step 2: Query the provider source for each of the providers we selected
	// in the first step and select the latest available version that is
	// in the set of acceptable versions.
	//
	// This produces a set of packages to install to our cache in the next step.
	need := map[addrs.Provider]getproviders.Version{}
NeedProvider:
	for provider, acceptableVersions := range mightNeed {
		if err := ctx.Err(); err != nil {
			// If our context has been cancelled or reached a timeout then
			// we'll abort early, because subsequent operations against
			// that context will fail immediately anyway.
			return nil, err
		}

		if cb := evts.QueryPackagesBegin; cb != nil {
			cb(provider, reqs[provider], locked[provider])
		}
		available, warnings, err := i.source.AvailableVersions(ctx, provider)
		if err != nil {
			// TODO: Consider retrying a few times for certain types of
			// source errors that seem likely to be transient.
			errs[provider] = err
			if cb := evts.QueryPackagesFailure; cb != nil {
				cb(provider, err)
			}
			// We will take no further actions for this provider.
			continue
		}
		if len(warnings) > 0 {
			if cb := evts.QueryPackagesWarning; cb != nil {
				cb(provider, warnings)
			}
		}
		available.Sort()                           // put the versions in increasing order of precedence
		for i := len(available) - 1; i >= 0; i-- { // walk backwards to consider newer versions first
			if acceptableVersions.Has(available[i]) {
				need[provider] = available[i]
				if cb := evts.QueryPackagesSuccess; cb != nil {
					cb(provider, available[i])
				}
				continue NeedProvider
			}
		}
		// If we get here then the source has no packages that meet the given
		// version constraint, which we model as a query error.
		if locked[provider] {
			// This situation should be a rare one: it suggests that a
			// version was previously available but was yanked for some
			// reason.
			lock := locks.Provider(provider)
			err = fmt.Errorf("the previously-selected version %s is no longer available", lock.Version())
		} else {
			err = fmt.Errorf("no available releases match the given constraints %s", getproviders.VersionConstraintsString(reqs[provider]))
		}
		errs[provider] = err
		if cb := evts.QueryPackagesFailure; cb != nil {
			cb(provider, err)
		}
	}

	// Step 3: For each provider version we've decided we need to install,
	// install its package into our target cache (possibly via the global cache).
	authResults := map[addrs.Provider]*getproviders.PackageAuthenticationResult{} // record auth results for all successfully fetched providers
	targetPlatform := i.targetDir.targetPlatform                                  // we inherit this to behave correctly in unit tests
	for provider, version := range need {
		if err := ctx.Err(); err != nil {
			// If our context has been cancelled or reached a timeout then
			// we'll abort early, because subsequent operations against
			// that context will fail immediately anyway.
			return nil, err
		}

		lock := locks.Provider(provider)
		var preferredHashes []getproviders.Hash
		if lock != nil && lock.Version() == version { // hash changes are expected if the version is also changing
			preferredHashes = lock.PreferredHashes()
		}

		// If our target directory already has the provider version that fulfills the lock file, carry on
		if installed := i.targetDir.ProviderVersion(provider, version); installed != nil {
			if len(preferredHashes) > 0 {
				if matches, _ := installed.MatchesAnyHash(preferredHashes); matches {
					if cb := evts.ProviderAlreadyInstalled; cb != nil {
						cb(provider, version)
					}
					continue
				}
			}
		}

		if i.globalCacheDir != nil {
			// Step 3a: If our global cache already has this version available then
			// we'll just link it in.
			if cached := i.globalCacheDir.ProviderVersion(provider, version); cached != nil {
				// An existing cache entry is only an acceptable choice
				// if there is already a lock file entry for this provider
				// and the cache entry matches its checksums.
				//
				// If there was no lock file entry at all then we need to
				// install the package for real so that we can lock as complete
				// as possible a set of checksums for all of this provider's
				// packages.
				//
				// If there was a lock file entry but the cache doesn't match
				// it then we assume that the lock file checksums were only
				// partially populated (e.g. from a local mirror where we can
				// only see one package to checksum it) and so we'll fetch
				// from upstream to see if the origin can give us a package
				// that _does_ match. This might still not work out, but if
				// it does then it allows us to avoid returning a checksum
				// mismatch error.
				acceptablePackage := false
				if len(preferredHashes) != 0 {
					var err error
					acceptablePackage, err = cached.MatchesAnyHash(preferredHashes)
					if err != nil {
						// If we can't calculate the checksum for the cached
						// package then we'll just treat it as a checksum failure.
						acceptablePackage = false
					}
				}

				if !acceptablePackage && i.globalCacheDirMayBreakDependencyLockFile {
					// The "may break dependency lock file" setting effectively
					// means that we'll accept any matching package that's
					// already in the cache, regardless of whether it matches
					// what's in the dependency lock file.
					//
					// That means two less-ideal situations might occur:
					// - If this provider is not currently tracked in the lock
					//   file at all then after installation the lock file will
					//   only accept the package that was already present in
					//   the cache as a valid checksum. That means the generated
					//   lock file won't be portable to other operating systems
					//   or CPU architectures.
					// - If the provider _is_ currently tracked in the lock file
					//   but the checksums there don't match what was in the
					//   cache then the LinkFromOtherCache call below will
					//   fail with a checksum error, and the user will need to
					//   either manually remove the entry from the lock file
					//   or remove the mismatching item from the cache,
					//   depending on which of these they prefer to use as the
					//   source of truth for the expected contents of the
					//   package.
					//
					// If the lock file already includes this provider and the
					// cache entry matches one of the locked checksums then
					// there's no problem, but in that case we wouldn't enter
					// this branch because acceptablePackage would already be
					// true from the check above.
					log.Printf(
						"[WARN] plugin_cache_may_break_dependency_lock_file: Using global cache dir package for %s v%s even though it doesn't match this configuration's dependency lock file",
						provider.String(), version.String(),
					)
					acceptablePackage = true
				}

				// TODO: Should we emit an event through the events object
				// for "there was an entry in the cache but we ignored it
				// because the checksum didn't match"? We can't use
				// LinkFromCacheFailure in that case because this isn't a
				// failure. For now we'll just be quiet about it.

				if acceptablePackage {
					if cb := evts.LinkFromCacheBegin; cb != nil {
						cb(provider, version, i.globalCacheDir.baseDir)
					}
					if _, err := cached.ExecutableFile(); err != nil {
						err := fmt.Errorf("provider binary not found: %s", err)
						errs[provider] = err
						if cb := evts.LinkFromCacheFailure; cb != nil {
							cb(provider, version, err)
						}
						continue
					}

					err := i.targetDir.LinkFromOtherCache(cached, preferredHashes)
					if err != nil {
						errs[provider] = err
						if cb := evts.LinkFromCacheFailure; cb != nil {
							cb(provider, version, err)
						}
						continue
					}
					// We'll fetch what we just linked to make sure it actually
					// did show up there.
					new := i.targetDir.ProviderVersion(provider, version)
					if new == nil {
						err := fmt.Errorf("after linking %s from provider cache at %s it is still not detected in the target directory; this is a bug in Terraform", provider, i.globalCacheDir.baseDir)
						errs[provider] = err
						if cb := evts.LinkFromCacheFailure; cb != nil {
							cb(provider, version, err)
						}
						continue
					}

					// The LinkFromOtherCache call above should've verified that
					// the package matches one of the hashes previously recorded,
					// if any. We'll now augment those hashes with one freshly
					// calculated from the package we just linked, which allows
					// the lock file to gradually transition to recording newer hash
					// schemes when they become available.
					var priorHashes []getproviders.Hash
					if lock != nil && lock.Version() == version {
						// If the version we're installing is identical to the
						// one we previously locked then we'll keep all of the
						// hashes we saved previously and add to it. Otherwise
						// we'll be starting fresh, because each version has its
						// own set of packages and thus its own hashes.
						priorHashes = append(priorHashes, preferredHashes...)

						// NOTE: The behavior here is unfortunate when a particular
						// provider version was already cached on the first time
						// the current configuration requested it, because that
						// means we don't currently get the opportunity to fetch
						// and verify the checksums for the new package from
						// upstream. That's currently unavoidable because upstream
						// checksums are in the "ziphash" format and so we can't
						// verify them against our cache directory's unpacked
						// packages: we'd need to go fetch the package from the
						// origin and compare against it, which would defeat the
						// purpose of the global cache.
						//
						// If we fetch from upstream on the first encounter with
						// a particular provider then we'll end up in the other
						// codepath below where we're able to also include the
						// checksums from the origin registry.
					}
					newHash, err := cached.Hash()
					if err != nil {
						err := fmt.Errorf("after linking %s from provider cache at %s, failed to compute a checksum for it: %s", provider, i.globalCacheDir.baseDir, err)
						errs[provider] = err
						if cb := evts.LinkFromCacheFailure; cb != nil {
							cb(provider, version, err)
						}
						continue
					}
					// The hashes slice gets deduplicated in the lock file
					// implementation, so we don't worry about potentially
					// creating a duplicate here.
					var newHashes []getproviders.Hash
					newHashes = append(newHashes, priorHashes...)
					newHashes = append(newHashes, newHash)
					locks.SetProvider(provider, version, reqs[provider], newHashes)
					if cb := evts.ProvidersLockUpdated; cb != nil {
						// We want to ensure that newHash and priorHashes are
						// sorted. newHash is a single value, so it's definitely
						// sorted. priorHashes are pulled from the lock file, so
						// are also already sorted.
						cb(provider, version, []getproviders.Hash{newHash}, nil, priorHashes)
					}

					if cb := evts.LinkFromCacheSuccess; cb != nil {
						cb(provider, version, new.PackageDir)
					}
					continue // Don't need to do full install, then.
				}
			}
		}

		// Step 3b: Get the package metadata for the selected version from our
		// provider source.
		//
		// This is the step where we might detect and report that the provider
		// isn't available for the current platform.
		if cb := evts.FetchPackageMeta; cb != nil {
			cb(provider, version)
		}
		meta, err := i.source.PackageMeta(ctx, provider, version, targetPlatform)
		if err != nil {
			errs[provider] = err
			if cb := evts.FetchPackageFailure; cb != nil {
				cb(provider, version, err)
			}
			continue
		}

		// Step 3c: Retrieve the package indicated by the metadata we received,
		// either directly into our target directory or via the global cache
		// directory.
		if cb := evts.FetchPackageBegin; cb != nil {
			cb(provider, version, meta.Location)
		}
		var installTo, linkTo *Dir
		if i.globalCacheDir != nil {
			installTo = i.globalCacheDir
			linkTo = i.targetDir
		} else {
			installTo = i.targetDir
			linkTo = nil // no linking needed
		}

		allowedHashes := preferredHashes
		if mode.forceInstallChecksums() {
			allowedHashes = []getproviders.Hash{}
		}

		authResult, err := installTo.InstallPackage(ctx, meta, allowedHashes)
		if err != nil {
			// TODO: Consider retrying for certain kinds of error that seem
			// likely to be transient. For now, we just treat all errors equally.
			errs[provider] = err
			if cb := evts.FetchPackageFailure; cb != nil {
				cb(provider, version, err)
			}
			continue
		}
		new := installTo.ProviderVersion(provider, version)
		if new == nil {
			err := fmt.Errorf("after installing %s it is still not detected in %s; this is a bug in Terraform", provider, installTo.BasePath())
			errs[provider] = err
			if cb := evts.FetchPackageFailure; cb != nil {
				cb(provider, version, err)
			}
			continue
		}
		if _, err := new.ExecutableFile(); err != nil {
			err := fmt.Errorf("provider binary not found: %s", err)
			errs[provider] = err
			if cb := evts.FetchPackageFailure; cb != nil {
				cb(provider, version, err)
			}
			continue
		}
		if linkTo != nil {
			// We skip emitting the "LinkFromCache..." events here because
			// it's simpler for the caller to treat them as mutually exclusive.
			// We can just subsume the linking step under the "FetchPackage..."
			// series here (and that's why we use FetchPackageFailure below).
			// We also don't do a hash check here because we already did that
			// as part of the installTo.InstallPackage call above.
			err := linkTo.LinkFromOtherCache(new, nil)
			if err != nil {
				errs[provider] = err
				if cb := evts.FetchPackageFailure; cb != nil {
					cb(provider, version, err)
				}
				continue
			}

			// We should now also find the package in the linkTo dir, which
			// gives us the final value of "new" where the path points in to
			// the true target directory, rather than possibly the global
			// cache directory.
			new = linkTo.ProviderVersion(provider, version)
			if new == nil {
				err := fmt.Errorf("after installing %s it is still not detected in %s; this is a bug in Terraform", provider, linkTo.BasePath())
				errs[provider] = err
				if cb := evts.FetchPackageFailure; cb != nil {
					cb(provider, version, err)
				}
				continue
			}
			if _, err := new.ExecutableFile(); err != nil {
				err := fmt.Errorf("provider binary not found: %s", err)
				errs[provider] = err
				if cb := evts.FetchPackageFailure; cb != nil {
					cb(provider, version, err)
				}
				continue
			}
		}
		authResults[provider] = authResult

		// The InstallPackage call above should've verified that
		// the package matches one of the hashes previously recorded,
		// if any. We'll now augment those hashes with a new set populated
		// with the hashes returned by the upstream source and from the
		// package we've just installed, which allows the lock file to
		// gradually transition to newer hash schemes when they become
		// available.
		//
		// This is assuming that if a package matches both a hash we saw before
		// _and_ a new hash then the new hash is a valid substitute for
		// the previous hash.
		//
		// The hashes slice gets deduplicated in the lock file
		// implementation, so we don't worry about potentially
		// creating duplicates here.
		var priorHashes []getproviders.Hash
		if lock != nil && lock.Version() == version {
			// If the version we're installing is identical to the
			// one we previously locked then we'll keep all of the
			// hashes we saved previously and add to it. Otherwise
			// we'll be starting fresh, because each version has its
			// own set of packages and thus its own hashes.
			priorHashes = append(priorHashes, preferredHashes...)
		}
		newHash, err := new.Hash()
		if err != nil {
			err := fmt.Errorf("after installing %s, failed to compute a checksum for it: %s", provider, err)
			errs[provider] = err
			if cb := evts.FetchPackageFailure; cb != nil {
				cb(provider, version, err)
			}
			continue
		}

		var signedHashes []getproviders.Hash
		if authResult.SignedByAnyParty() {
			// We'll trust new hashes from upstream only if they were verified
			// as signed by a suitable key. Otherwise, we'd record only
			// a new hash we just calculated ourselves from the bytes on disk,
			// and so the hashes would cover only the current platform.
			signedHashes = append(signedHashes, meta.AcceptableHashes()...)
		}

		var newHashes []getproviders.Hash
		newHashes = append(newHashes, newHash)
		newHashes = append(newHashes, priorHashes...)
		newHashes = append(newHashes, signedHashes...)

		locks.SetProvider(provider, version, reqs[provider], newHashes)
		if cb := evts.ProvidersLockUpdated; cb != nil {
			// newHash and priorHashes are already sorted.
			// But we do need to sort signedHashes so we can reason about it
			// sensibly.
			sort.Slice(signedHashes, func(i, j int) bool {
				return string(signedHashes[i]) < string(signedHashes[j])
			})

			cb(provider, version, []getproviders.Hash{newHash}, signedHashes, priorHashes)
		}

		if cb := evts.FetchPackageSuccess; cb != nil {
			cb(provider, version, new.PackageDir, authResult)
		}
	}

	// Emit final event for fetching if any were successfully fetched
	if cb := evts.ProvidersFetched; cb != nil && len(authResults) > 0 {
		cb(authResults)
	}

	// Finally, if the lock structure contains locks for any providers that
	// are no longer needed by this configuration, we'll remove them. This
	// is important because we will not have installed those providers
	// above and so a lock file still containing them would make the working
	// directory invalid: not every provider in the lock file is available
	// for use.
	for providerAddr := range locks.AllProviders() {
		if _, ok := reqs[providerAddr]; !ok {
			locks.RemoveProvider(providerAddr)
		}
	}

	if len(errs) > 0 {
		return locks, InstallerError{
			ProviderErrors: errs,
		}
	}
	return locks, nil
}

// InstallMode customizes the details of how an install operation treats
// providers that have versions already cached in the target directory.
type InstallMode rune

const (
	// InstallNewProvidersOnly is an InstallMode that causes the installer
	// to accept any existing version of a requested provider that is already
	// cached as long as it's in the given version sets, without checking
	// whether new versions are available that are also in the given version
	// sets.
	InstallNewProvidersOnly InstallMode = 'N'

	// InstallNewProvidersForce is an InstallMode that follows the same
	// logic as InstallNewProvidersOnly except it does not verify existing
	// checksums but force installs new checksums for all given providers.
	InstallNewProvidersForce InstallMode = 'F'

	// InstallUpgrades is an InstallMode that causes the installer to check
	// all requested providers to see if new versions are available that
	// are also in the given version sets, even if a suitable version of
	// a given provider is already available.
	InstallUpgrades InstallMode = 'U'
)

func (m InstallMode) forceQueryAllProviders() bool {
	return m == InstallUpgrades
}

func (m InstallMode) forceInstallChecksums() bool {
	return m == InstallNewProvidersForce
}

// InstallerError is an error type that may be returned (but is not guaranteed)
// from Installer.EnsureProviderVersions to indicate potentially several
// separate failed installation outcomes for different providers included in
// the overall request.
type InstallerError struct {
	ProviderErrors map[addrs.Provider]error
}

func (err InstallerError) Error() string {
	addrs := make([]addrs.Provider, 0, len(err.ProviderErrors))
	for addr := range err.ProviderErrors {
		addrs = append(addrs, addr)
	}
	sort.Slice(addrs, func(i, j int) bool {
		return addrs[i].LessThan(addrs[j])
	})
	var b strings.Builder
	b.WriteString("some providers could not be installed:\n")
	for _, addr := range addrs {
		providerErr := err.ProviderErrors[addr]
		fmt.Fprintf(&b, "- %s: %s\n", addr, providerErr)
	}
	return strings.TrimSpace(b.String())
}
