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

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)
}
