package depsfile

import (
	"fmt"
	"sort"

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

// Locks is the top-level type representing the information retained in a
// dependency lock file.
//
// Locks and the other types used within it are mutable via various setter
// methods, but they are not safe for concurrent  modifications, so it's the
// caller's responsibility to prevent concurrent writes and writes concurrent
// with reads.
type Locks struct {
	providers map[addrs.Provider]*ProviderLock

	// overriddenProviders is a subset of providers which we might be tracking
	// in field providers but whose lock information we're disregarding for
	// this particular run due to some feature that forces Terraform to not
	// use a normally-installed plugin for it. For example, the "provider dev
	// overrides" feature means that we'll be using an arbitrary directory on
	// disk as the package, regardless of what might be selected in "providers".
	//
	// overriddenProviders is an in-memory-only annotation, never stored as
	// part of a lock file and thus not persistent between Terraform runs.
	// The CLI layer is generally the one responsible for populating this,
	// by calling SetProviderOverridden in response to CLI Configuration
	// settings, environment variables, or whatever similar sources.
	overriddenProviders map[addrs.Provider]struct{}

	// TODO: In future we'll also have module locks, but the design of that
	// still needs some more work and we're deferring that to get the
	// provider locking capability out sooner, because it's more common to
	// directly depend on providers maintained outside your organization than
	// modules maintained outside your organization.

	// sources is a copy of the map of source buffers produced by the HCL
	// parser during loading, which we retain only so that the caller can
	// use it to produce source code snippets in error messages.
	sources map[string][]byte
}

// NewLocks constructs and returns a new Locks object that initially contains
// no locks at all.
func NewLocks() *Locks {
	return &Locks{
		providers: make(map[addrs.Provider]*ProviderLock),

		// no "sources" here, because that's only for locks objects loaded
		// from files.
	}
}

// Provider returns the stored lock for the given provider, or nil if that
// provider currently has no lock.
func (l *Locks) Provider(addr addrs.Provider) *ProviderLock {
	return l.providers[addr]
}

// AllProviders returns a map describing all of the provider locks in the
// receiver.
func (l *Locks) AllProviders() map[addrs.Provider]*ProviderLock {
	// We return a copy of our internal map so that future calls to
	// SetProvider won't modify the map we're returning, or vice-versa.
	ret := make(map[addrs.Provider]*ProviderLock, len(l.providers))
	for k, v := range l.providers {
		ret[k] = v
	}
	return ret
}

// SetProvider creates a new lock or replaces the existing lock for the given
// provider.
//
// SetProvider returns the newly-created provider lock object, which
// invalidates any ProviderLock object previously returned from Provider or
// SetProvider for the given provider address.
//
// The ownership of the backing array for the slice of hashes passes to this
// function, and so the caller must not read or write that backing array after
// calling SetProvider.
//
// Only lockable providers can be passed to this method. If you pass a
// non-lockable provider address then this function will panic. Use
// function ProviderIsLockable to determine whether a particular provider
// should participate in the version locking mechanism.
func (l *Locks) SetProvider(addr addrs.Provider, version getproviders.Version, constraints getproviders.VersionConstraints, hashes []getproviders.Hash) *ProviderLock {
	if !ProviderIsLockable(addr) {
		panic(fmt.Sprintf("Locks.SetProvider with non-lockable provider %s", addr))
	}

	new := NewProviderLock(addr, version, constraints, hashes)
	l.providers[new.addr] = new
	return new
}

// RemoveProvider removes any existing lock file entry for the given provider.
//
// If the given provider did not already have a lock entry, RemoveProvider is
// a no-op.
//
// Only lockable providers can be passed to this method. If you pass a
// non-lockable provider address then this function will panic. Use
// function ProviderIsLockable to determine whether a particular provider
// should participate in the version locking mechanism.
func (l *Locks) RemoveProvider(addr addrs.Provider) {
	if !ProviderIsLockable(addr) {
		panic(fmt.Sprintf("Locks.RemoveProvider with non-lockable provider %s", addr))
	}

	delete(l.providers, addr)
}

// SetProviderOverridden records that this particular Terraform process will
// not pay attention to the recorded lock entry for the given provider, and
// will instead access that provider's functionality in some other special
// way that isn't sensitive to provider version selections or checksums.
//
// This is an in-memory-only annotation which lives only inside a particular
// Locks object, and is never persisted as part of a saved lock file on disk.
// It's valid to still use other methods of the reciever to access
// already-stored lock information and to update lock information for an
// overridden provider, but some callers may need to use ProviderIsOverridden
// to selectively disregard stored lock information for overridden providers,
// depending on what they intended to use the lock information for.
func (l *Locks) SetProviderOverridden(addr addrs.Provider) {
	if l.overriddenProviders == nil {
		l.overriddenProviders = make(map[addrs.Provider]struct{})
	}
	l.overriddenProviders[addr] = struct{}{}
}

// ProviderIsOverridden returns true only if the given provider address was
// previously registered as overridden by calling SetProviderOverridden.
func (l *Locks) ProviderIsOverridden(addr addrs.Provider) bool {
	_, ret := l.overriddenProviders[addr]
	return ret
}

// SetSameOverriddenProviders updates the receiver to mark as overridden all
// of the same providers already marked as overridden in the other given locks.
//
// This allows propagating override information between different lock objects,
// as if calling SetProviderOverridden for each address already overridden
// in the other given locks. If the reciever already has overridden providers,
// SetSameOverriddenProviders will preserve them.
func (l *Locks) SetSameOverriddenProviders(other *Locks) {
	if other == nil {
		return
	}
	for addr := range other.overriddenProviders {
		l.SetProviderOverridden(addr)
	}
}

// NewProviderLock creates a new ProviderLock object that isn't associated
// with any Locks object.
//
// This is here primarily for testing. Most callers should use Locks.SetProvider
// to construct a new provider lock and insert it into a Locks object at the
// same time.
//
// The ownership of the backing array for the slice of hashes passes to this
// function, and so the caller must not read or write that backing array after
// calling NewProviderLock.
//
// Only lockable providers can be passed to this method. If you pass a
// non-lockable provider address then this function will panic. Use
// function ProviderIsLockable to determine whether a particular provider
// should participate in the version locking mechanism.
func NewProviderLock(addr addrs.Provider, version getproviders.Version, constraints getproviders.VersionConstraints, hashes []getproviders.Hash) *ProviderLock {
	if !ProviderIsLockable(addr) {
		panic(fmt.Sprintf("Locks.NewProviderLock with non-lockable provider %s", addr))
	}

	// Normalize the hashes into lexical order so that we can do straightforward
	// equality tests between different locks for the same provider. The
	// hashes are logically a set, so the given order is insignificant.
	sort.Slice(hashes, func(i, j int) bool {
		return string(hashes[i]) < string(hashes[j])
	})

	// This is a slightly-tricky in-place deduping to avoid unnecessarily
	// allocating a new array in the common case where there are no duplicates:
	// we iterate over "hashes" at the same time as appending to another slice
	// with the same backing array, relying on the fact that deduping can only
	// _skip_ elements from the input, and will never generate additional ones
	// that would cause the writer to get ahead of the reader. This also
	// assumes that we already sorted the items, which means that any duplicates
	// will be consecutive in the sequence.
	dedupeHashes := hashes[:0]
	prevHash := getproviders.NilHash
	for _, hash := range hashes {
		if hash != prevHash {
			dedupeHashes = append(dedupeHashes, hash)
			prevHash = hash
		}
	}

	return &ProviderLock{
		addr:               addr,
		version:            version,
		versionConstraints: constraints,
		hashes:             dedupeHashes,
	}
}

// ProviderIsLockable returns true if the given provider is eligible for
// version locking.
//
// Currently, all providers except builtin and legacy providers are eligible
// for locking.
func ProviderIsLockable(addr addrs.Provider) bool {
	return !(addr.IsBuiltIn() || addr.IsLegacy())
}

// Sources returns the source code of the file the receiver was generated from,
// or an empty map if the receiver wasn't generated from a file.
//
// This return type matches the one expected by HCL diagnostics printers to
// produce source code snapshots, which is the only intended use for this
// method.
func (l *Locks) Sources() map[string][]byte {
	return l.sources
}

// Equal returns true if the given Locks represents the same information as
// the receiver.
//
// Equal explicitly _does not_ consider the equality of version constraints
// in the saved locks, because those are saved only as hints to help the UI
// explain what's changed between runs, and are never used as part of
// dependency installation decisions.
func (l *Locks) Equal(other *Locks) bool {
	if len(l.providers) != len(other.providers) {
		return false
	}
	for addr, thisLock := range l.providers {
		otherLock, ok := other.providers[addr]
		if !ok {
			return false
		}

		if thisLock.addr != otherLock.addr {
			// It'd be weird to get here because we already looked these up
			// by address above.
			return false
		}
		if thisLock.version != otherLock.version {
			// Equality rather than "Version.Same" because changes to the
			// build metadata are significant for the purpose of this function:
			// it's a different package even if it has the same precedence.
			return false
		}

		// Although "hashes" is declared as a slice, it's logically an
		// unordered set. However, we normalize the slice of hashes when
		// recieving it in NewProviderLock, so we can just do a simple
		// item-by-item equality test here.
		if len(thisLock.hashes) != len(otherLock.hashes) {
			return false
		}
		for i := range thisLock.hashes {
			if thisLock.hashes[i] != otherLock.hashes[i] {
				return false
			}
		}
	}
	// We don't need to worry about providers that are in "other" but not
	// in the receiver, because we tested the lengths being equal above.

	return true
}

// EqualProviderAddress returns true if the given Locks have the same provider
// address as the receiver. This doesn't check version and hashes.
func (l *Locks) EqualProviderAddress(other *Locks) bool {
	if len(l.providers) != len(other.providers) {
		return false
	}

	for addr := range l.providers {
		_, ok := other.providers[addr]
		if !ok {
			return false
		}
	}

	return true
}

// Empty returns true if the given Locks object contains no actual locks.
//
// UI code might wish to use this to distinguish a lock file being
// written for the first time from subsequent updates to that lock file.
func (l *Locks) Empty() bool {
	return len(l.providers) == 0
}

// DeepCopy creates a new Locks that represents the same information as the
// receiver but does not share memory for any parts of the structure that.
// are mutable through methods on Locks.
//
// Note that this does _not_ create deep copies of parts of the structure
// that are technically mutable but are immutable by convention, such as the
// array underlying the slice of version constraints. Callers may mutate the
// resulting data structure only via the direct methods of Locks.
func (l *Locks) DeepCopy() *Locks {
	ret := NewLocks()
	for addr, lock := range l.providers {
		var hashes []getproviders.Hash
		if len(lock.hashes) > 0 {
			hashes = make([]getproviders.Hash, len(lock.hashes))
			copy(hashes, lock.hashes)
		}
		ret.SetProvider(addr, lock.version, lock.versionConstraints, hashes)
	}
	return ret
}

// ProviderLock represents lock information for a specific provider.
type ProviderLock struct {
	// addr is the address of the provider this lock applies to.
	addr addrs.Provider

	// version is the specific version that was previously selected, while
	// versionConstraints is the constraint that was used to make that
	// selection, which we can potentially use to hint to run
	// e.g. terraform init -upgrade if a user has changed a version
	// constraint but the previous selection still remains valid.
	// "version" is therefore authoritative, while "versionConstraints" is
	// just for a UI hint and not used to make any real decisions.
	version            getproviders.Version
	versionConstraints getproviders.VersionConstraints

	// hashes contains zero or more hashes of packages or package contents
	// for the package associated with the selected version across all of
	// the supported platforms.
	//
	// hashes can contain a mixture of hashes in different formats to support
	// changes over time. The new-style hash format is to have a string
	// starting with "h" followed by a version number and then a colon, like
	// "h1:" for the first hash format version. Other hash versions following
	// this scheme may come later. These versioned hash schemes are implemented
	// in the getproviders package; for example, "h1:" is implemented in
	// getproviders.HashV1 .
	//
	// There is also a legacy hash format which is just a lowercase-hex-encoded
	// SHA256 hash of the official upstream .zip file for the selected version.
	// We'll allow as that a stop-gap until we can upgrade Terraform Registry
	// to support the new scheme, but is non-ideal because we can verify it only
	// when we have the original .zip file exactly; we can't verify a local
	// directory containing the unpacked contents of that .zip file.
	//
	// We ideally want to populate hashes for all available platforms at
	// once, by referring to the signed checksums file in the upstream
	// registry. In that ideal case it's possible to later work with the same
	// configuration on a different platform while still verifying the hashes.
	// However, installation from any method other than an origin registry
	// means we can only populate the hash for the current platform, and so
	// it won't be possible to verify a subsequent installation of the same
	// provider on a different platform.
	hashes []getproviders.Hash
}

// Provider returns the address of the provider this lock applies to.
func (l *ProviderLock) Provider() addrs.Provider {
	return l.addr
}

// Version returns the currently-selected version for the corresponding provider.
func (l *ProviderLock) Version() getproviders.Version {
	return l.version
}

// VersionConstraints returns the version constraints that were recorded as
// being used to choose the version returned by Version.
//
// These version constraints are not authoritative for future selections and
// are included only so Terraform can detect if the constraints in
// configuration have changed since a selection was made, and thus hint to the
// user that they may need to run terraform init -upgrade to apply the new
// constraints.
func (l *ProviderLock) VersionConstraints() getproviders.VersionConstraints {
	return l.versionConstraints
}

// AllHashes returns all of the package hashes that were recorded when this
// lock was created. If no hashes were recorded for that platform, the result
// is a zero-length slice.
//
// If your intent is to verify a package against the recorded hashes, use
// PreferredHashes to get only the hashes which the current version
// of Terraform considers the strongest of the available hashing schemes, one
// of which must match in order for verification to be considered successful.
//
// Do not modify the backing array of the returned slice.
func (l *ProviderLock) AllHashes() []getproviders.Hash {
	return l.hashes
}

// ContainsAll returns true if the hashes in this ProviderLock contains
// all the hashes in the target.
//
// This function assumes the hashes are in each ProviderLock are sorted.
// If the ProviderLock was created by the NewProviderLock constructor then
// the hashes are guaranteed to be sorted.
func (l *ProviderLock) ContainsAll(target *ProviderLock) bool {
	if target == nil || len(target.hashes) == 0 {
		return true
	}

	targetIndex := 0
	for ix := 0; ix < len(l.hashes); ix++ {
		if l.hashes[ix] == target.hashes[targetIndex] {
			targetIndex++

			if targetIndex >= len(target.hashes) {
				return true
			}
		}
	}
	return false
}

// PreferredHashes returns a filtered version of the AllHashes return value
// which includes only the strongest of the availabile hash schemes, in
// case legacy hash schemes are deprecated over time but still supported for
// upgrade purposes.
//
// At least one of the given hashes must match for a package to be considered
// valud.
func (l *ProviderLock) PreferredHashes() []getproviders.Hash {
	return getproviders.PreferredHashes(l.hashes)
}
