package plans

import (
	"fmt"
	"sync"

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

// ChangesSync is a wrapper around a Changes that provides a concurrency-safe
// interface to insert new changes and retrieve copies of existing changes.
//
// Each ChangesSync is independent of all others, so all concurrent writers
// to a particular Changes must share a single ChangesSync. Behavior is
// undefined if any other caller makes changes to the underlying Changes
// object or its nested objects concurrently with any of the methods of a
// particular ChangesSync.
type ChangesSync struct {
	lock    sync.Mutex
	changes *Changes
}

// AppendResourceInstanceChange records the given resource instance change in
// the set of planned resource changes.
//
// The caller must ensure that there are no concurrent writes to the given
// change while this method is running, but it is safe to resume mutating
// it after this method returns without affecting the saved change.
func (cs *ChangesSync) AppendResourceInstanceChange(changeSrc *ResourceInstanceChangeSrc) {
	if cs == nil {
		panic("AppendResourceInstanceChange on nil ChangesSync")
	}
	cs.lock.Lock()
	defer cs.lock.Unlock()

	s := changeSrc.DeepCopy()
	cs.changes.Resources = append(cs.changes.Resources, s)
}

// GetResourceInstanceChange searches the set of resource instance changes for
// one matching the given address and generation, returning it if it exists.
//
// If no such change exists, nil is returned.
//
// The returned object is a deep copy of the change recorded in the plan, so
// callers may mutate it although it's generally better (less confusing) to
// treat planned changes as immutable after they've been initially constructed.
func (cs *ChangesSync) GetResourceInstanceChange(addr addrs.AbsResourceInstance, gen states.Generation) *ResourceInstanceChangeSrc {
	if cs == nil {
		panic("GetResourceInstanceChange on nil ChangesSync")
	}
	cs.lock.Lock()
	defer cs.lock.Unlock()

	if gen == states.CurrentGen {
		return cs.changes.ResourceInstance(addr).DeepCopy()
	}
	if dk, ok := gen.(states.DeposedKey); ok {
		return cs.changes.ResourceInstanceDeposed(addr, dk).DeepCopy()
	}
	panic(fmt.Sprintf("unsupported generation value %#v", gen))
}

// GetChangesForConfigResource searches the set of resource instance
// changes and returns all changes related to a given configuration address.
// This is be used to find possible changes related to a configuration
// reference.
//
// If no such changes exist, nil is returned.
//
// The returned objects are a deep copy of the change recorded in the plan, so
// callers may mutate them although it's generally better (less confusing) to
// treat planned changes as immutable after they've been initially constructed.
func (cs *ChangesSync) GetChangesForConfigResource(addr addrs.ConfigResource) []*ResourceInstanceChangeSrc {
	if cs == nil {
		panic("GetChangesForConfigResource on nil ChangesSync")
	}
	cs.lock.Lock()
	defer cs.lock.Unlock()
	var changes []*ResourceInstanceChangeSrc
	for _, c := range cs.changes.InstancesForConfigResource(addr) {
		changes = append(changes, c.DeepCopy())
	}
	return changes
}

// GetChangesForAbsResource searches the set of resource instance
// changes and returns all changes related to a given configuration address.
//
// If no such changes exist, nil is returned.
//
// The returned objects are a deep copy of the change recorded in the plan, so
// callers may mutate them although it's generally better (less confusing) to
// treat planned changes as immutable after they've been initially constructed.
func (cs *ChangesSync) GetChangesForAbsResource(addr addrs.AbsResource) []*ResourceInstanceChangeSrc {
	if cs == nil {
		panic("GetChangesForAbsResource on nil ChangesSync")
	}
	cs.lock.Lock()
	defer cs.lock.Unlock()
	var changes []*ResourceInstanceChangeSrc
	for _, c := range cs.changes.InstancesForAbsResource(addr) {
		changes = append(changes, c.DeepCopy())
	}
	return changes
}

// RemoveResourceInstanceChange searches the set of resource instance changes
// for one matching the given address and generation, and removes it from the
// set if it exists.
func (cs *ChangesSync) RemoveResourceInstanceChange(addr addrs.AbsResourceInstance, gen states.Generation) {
	if cs == nil {
		panic("RemoveResourceInstanceChange on nil ChangesSync")
	}
	cs.lock.Lock()
	defer cs.lock.Unlock()

	dk := states.NotDeposed
	if realDK, ok := gen.(states.DeposedKey); ok {
		dk = realDK
	}

	addrStr := addr.String()
	for i, r := range cs.changes.Resources {
		if r.Addr.String() != addrStr || r.DeposedKey != dk {
			continue
		}
		copy(cs.changes.Resources[i:], cs.changes.Resources[i+1:])
		cs.changes.Resources = cs.changes.Resources[:len(cs.changes.Resources)-1]
		return
	}
}

// AppendOutputChange records the given output value change in the set of
// planned value changes.
//
// The caller must ensure that there are no concurrent writes to the given
// change while this method is running, but it is safe to resume mutating
// it after this method returns without affecting the saved change.
func (cs *ChangesSync) AppendOutputChange(changeSrc *OutputChangeSrc) {
	if cs == nil {
		panic("AppendOutputChange on nil ChangesSync")
	}
	cs.lock.Lock()
	defer cs.lock.Unlock()

	s := changeSrc.DeepCopy()
	cs.changes.Outputs = append(cs.changes.Outputs, s)
}

// GetOutputChange searches the set of output value changes for one matching
// the given address, returning it if it exists.
//
// If no such change exists, nil is returned.
//
// The returned object is a deep copy of the change recorded in the plan, so
// callers may mutate it although it's generally better (less confusing) to
// treat planned changes as immutable after they've been initially constructed.
func (cs *ChangesSync) GetOutputChange(addr addrs.AbsOutputValue) *OutputChangeSrc {
	if cs == nil {
		panic("GetOutputChange on nil ChangesSync")
	}
	cs.lock.Lock()
	defer cs.lock.Unlock()

	return cs.changes.OutputValue(addr)
}

// GetRootOutputChanges searches the set of output changes for any that reside
// the root module. If no such changes exist, nil is returned.
//
// The returned objects are a deep copy of the change recorded in the plan, so
// callers may mutate them although it's generally better (less confusing) to
// treat planned changes as immutable after they've been initially constructed.
func (cs *ChangesSync) GetRootOutputChanges() []*OutputChangeSrc {
	if cs == nil {
		panic("GetRootOutputChanges on nil ChangesSync")
	}
	cs.lock.Lock()
	defer cs.lock.Unlock()

	return cs.changes.RootOutputValues()
}

// GetOutputChanges searches the set of output changes for any that reside in
// module instances beneath the given module. If no changes exist, nil
// is returned.
//
// The returned objects are a deep copy of the change recorded in the plan, so
// callers may mutate them although it's generally better (less confusing) to
// treat planned changes as immutable after they've been initially constructed.
func (cs *ChangesSync) GetOutputChanges(parent addrs.ModuleInstance, module addrs.ModuleCall) []*OutputChangeSrc {
	if cs == nil {
		panic("GetOutputChange on nil ChangesSync")
	}
	cs.lock.Lock()
	defer cs.lock.Unlock()

	return cs.changes.OutputValues(parent, module)
}

// RemoveOutputChange searches the set of output value changes for one matching
// the given address, and removes it from the set if it exists.
func (cs *ChangesSync) RemoveOutputChange(addr addrs.AbsOutputValue) {
	if cs == nil {
		panic("RemoveOutputChange on nil ChangesSync")
	}
	cs.lock.Lock()
	defer cs.lock.Unlock()

	addrStr := addr.String()

	for i, o := range cs.changes.Outputs {
		if o.Addr.String() != addrStr {
			continue
		}
		copy(cs.changes.Outputs[i:], cs.changes.Outputs[i+1:])
		cs.changes.Outputs = cs.changes.Outputs[:len(cs.changes.Outputs)-1]
		return
	}
}
