package addrs

import (
	"fmt"
	"strings"
)

// Resource is an address for a resource block within configuration, which
// contains potentially-multiple resource instances if that configuration
// block uses "count" or "for_each".
type Resource struct {
	referenceable
	Mode ResourceMode
	Type string
	Name string
}

func (r Resource) String() string {
	switch r.Mode {
	case ManagedResourceMode:
		return fmt.Sprintf("%s.%s", r.Type, r.Name)
	case DataResourceMode:
		return fmt.Sprintf("data.%s.%s", r.Type, r.Name)
	default:
		// Should never happen, but we'll return a string here rather than
		// crashing just in case it does.
		return fmt.Sprintf("<invalid>.%s.%s", r.Type, r.Name)
	}
}

func (r Resource) Equal(o Resource) bool {
	return r.Mode == o.Mode && r.Name == o.Name && r.Type == o.Type
}

func (r Resource) Less(o Resource) bool {
	switch {
	case r.Mode != o.Mode:
		return r.Mode == DataResourceMode

	case r.Type != o.Type:
		return r.Type < o.Type

	case r.Name != o.Name:
		return r.Name < o.Name

	default:
		return false
	}
}

func (r Resource) UniqueKey() UniqueKey {
	return r // A Resource is its own UniqueKey
}

func (r Resource) uniqueKeySigil() {}

// Instance produces the address for a specific instance of the receiver
// that is idenfied by the given key.
func (r Resource) Instance(key InstanceKey) ResourceInstance {
	return ResourceInstance{
		Resource: r,
		Key:      key,
	}
}

// Absolute returns an AbsResource from the receiver and the given module
// instance address.
func (r Resource) Absolute(module ModuleInstance) AbsResource {
	return AbsResource{
		Module:   module,
		Resource: r,
	}
}

// InModule returns a ConfigResource from the receiver and the given module
// address.
func (r Resource) InModule(module Module) ConfigResource {
	return ConfigResource{
		Module:   module,
		Resource: r,
	}
}

// ImpliedProvider returns the implied provider type name, for e.g. the "aws" in
// "aws_instance"
func (r Resource) ImpliedProvider() string {
	typeName := r.Type
	if under := strings.Index(typeName, "_"); under != -1 {
		typeName = typeName[:under]
	}

	return typeName
}

// ResourceInstance is an address for a specific instance of a resource.
// When a resource is defined in configuration with "count" or "for_each" it
// produces zero or more instances, which can be addressed using this type.
type ResourceInstance struct {
	referenceable
	Resource Resource
	Key      InstanceKey
}

func (r ResourceInstance) ContainingResource() Resource {
	return r.Resource
}

func (r ResourceInstance) String() string {
	if r.Key == NoKey {
		return r.Resource.String()
	}
	return r.Resource.String() + r.Key.String()
}

func (r ResourceInstance) Equal(o ResourceInstance) bool {
	return r.Key == o.Key && r.Resource.Equal(o.Resource)
}

func (r ResourceInstance) Less(o ResourceInstance) bool {
	if !r.Resource.Equal(o.Resource) {
		return r.Resource.Less(o.Resource)
	}

	if r.Key != o.Key {
		return InstanceKeyLess(r.Key, o.Key)
	}

	return false
}

func (r ResourceInstance) UniqueKey() UniqueKey {
	return r // A ResourceInstance is its own UniqueKey
}

func (r ResourceInstance) uniqueKeySigil() {}

// Absolute returns an AbsResourceInstance from the receiver and the given module
// instance address.
func (r ResourceInstance) Absolute(module ModuleInstance) AbsResourceInstance {
	return AbsResourceInstance{
		Module:   module,
		Resource: r,
	}
}

// AbsResource is an absolute address for a resource under a given module path.
type AbsResource struct {
	targetable
	Module   ModuleInstance
	Resource Resource
}

// Resource returns the address of a particular resource within the receiver.
func (m ModuleInstance) Resource(mode ResourceMode, typeName string, name string) AbsResource {
	return AbsResource{
		Module: m,
		Resource: Resource{
			Mode: mode,
			Type: typeName,
			Name: name,
		},
	}
}

// Instance produces the address for a specific instance of the receiver
// that is idenfied by the given key.
func (r AbsResource) Instance(key InstanceKey) AbsResourceInstance {
	return AbsResourceInstance{
		Module:   r.Module,
		Resource: r.Resource.Instance(key),
	}
}

// Config returns the unexpanded ConfigResource for this AbsResource.
func (r AbsResource) Config() ConfigResource {
	return ConfigResource{
		Module:   r.Module.Module(),
		Resource: r.Resource,
	}
}

// TargetContains implements Targetable by returning true if the given other
// address is either equal to the receiver or is an instance of the
// receiver.
func (r AbsResource) TargetContains(other Targetable) bool {
	switch to := other.(type) {

	case AbsResource:
		// We'll use our stringification as a cheat-ish way to test for equality.
		return to.String() == r.String()

	case ConfigResource:
		// if an absolute resource from parsing a target address contains a
		// ConfigResource, the string representation will match
		return to.String() == r.String()

	case AbsResourceInstance:
		return r.TargetContains(to.ContainingResource())

	default:
		return false

	}
}

func (r AbsResource) AddrType() TargetableAddrType {
	return AbsResourceAddrType
}

func (r AbsResource) String() string {
	if len(r.Module) == 0 {
		return r.Resource.String()
	}
	return fmt.Sprintf("%s.%s", r.Module.String(), r.Resource.String())
}

// AffectedAbsResource returns the AbsResource.
func (r AbsResource) AffectedAbsResource() AbsResource {
	return r
}

func (r AbsResource) Equal(o AbsResource) bool {
	return r.Module.Equal(o.Module) && r.Resource.Equal(o.Resource)
}

func (r AbsResource) Less(o AbsResource) bool {
	if !r.Module.Equal(o.Module) {
		return r.Module.Less(o.Module)
	}

	if !r.Resource.Equal(o.Resource) {
		return r.Resource.Less(o.Resource)
	}

	return false
}

func (r AbsResource) absMoveableSigil() {
	// AbsResource is moveable
}

type absResourceKey string

func (r absResourceKey) uniqueKeySigil() {}

func (r AbsResource) UniqueKey() UniqueKey {
	return absResourceKey(r.String())
}

// AbsResourceInstance is an absolute address for a resource instance under a
// given module path.
type AbsResourceInstance struct {
	targetable
	Module   ModuleInstance
	Resource ResourceInstance
}

// ResourceInstance returns the address of a particular resource instance within the receiver.
func (m ModuleInstance) ResourceInstance(mode ResourceMode, typeName string, name string, key InstanceKey) AbsResourceInstance {
	return AbsResourceInstance{
		Module: m,
		Resource: ResourceInstance{
			Resource: Resource{
				Mode: mode,
				Type: typeName,
				Name: name,
			},
			Key: key,
		},
	}
}

// ContainingResource returns the address of the resource that contains the
// receving resource instance. In other words, it discards the key portion
// of the address to produce an AbsResource value.
func (r AbsResourceInstance) ContainingResource() AbsResource {
	return AbsResource{
		Module:   r.Module,
		Resource: r.Resource.ContainingResource(),
	}
}

// ConfigResource returns the address of the configuration block that declared
// this instance.
func (r AbsResourceInstance) ConfigResource() ConfigResource {
	return ConfigResource{
		Module:   r.Module.Module(),
		Resource: r.Resource.Resource,
	}
}

// TargetContains implements Targetable by returning true if the given other
// address is equal to the receiver.
func (r AbsResourceInstance) TargetContains(other Targetable) bool {
	switch to := other.(type) {

	// while we currently don't start with an AbsResourceInstance as a target
	// address, check all resource types for consistency.
	case AbsResourceInstance:
		// We'll use our stringification as a cheat-ish way to test for equality.
		return to.String() == r.String()
	case ConfigResource:
		return to.String() == r.String()
	case AbsResource:
		return to.String() == r.String()

	default:
		return false

	}
}

func (r AbsResourceInstance) AddrType() TargetableAddrType {
	return AbsResourceInstanceAddrType
}

func (r AbsResourceInstance) String() string {
	if len(r.Module) == 0 {
		return r.Resource.String()
	}
	return fmt.Sprintf("%s.%s", r.Module.String(), r.Resource.String())
}

// AffectedAbsResource returns the AbsResource for the instance.
func (r AbsResourceInstance) AffectedAbsResource() AbsResource {
	return AbsResource{
		Module:   r.Module,
		Resource: r.Resource.Resource,
	}
}

func (r AbsResourceInstance) Check(t CheckType, i int) Check {
	return Check{
		Container: r,
		Type:      t,
		Index:     i,
	}
}

func (v AbsResourceInstance) CheckableKind() CheckableKind {
	return CheckableResource
}

func (r AbsResourceInstance) Equal(o AbsResourceInstance) bool {
	return r.Module.Equal(o.Module) && r.Resource.Equal(o.Resource)
}

// Less returns true if the receiver should sort before the given other value
// in a sorted list of addresses.
func (r AbsResourceInstance) Less(o AbsResourceInstance) bool {
	if !r.Module.Equal(o.Module) {
		return r.Module.Less(o.Module)
	}

	if !r.Resource.Equal(o.Resource) {
		return r.Resource.Less(o.Resource)
	}

	return false
}

// AbsResourceInstance is a Checkable
func (r AbsResourceInstance) checkableSigil() {}

func (r AbsResourceInstance) ConfigCheckable() ConfigCheckable {
	// The ConfigCheckable for an AbsResourceInstance is its ConfigResource.
	return r.ConfigResource()
}

type absResourceInstanceKey string

func (r AbsResourceInstance) UniqueKey() UniqueKey {
	return absResourceInstanceKey(r.String())
}

func (r absResourceInstanceKey) uniqueKeySigil() {}

func (r AbsResourceInstance) absMoveableSigil() {
	// AbsResourceInstance is moveable
}

// ConfigResource is an address for a resource within a configuration.
type ConfigResource struct {
	targetable
	Module   Module
	Resource Resource
}

// Resource returns the address of a particular resource within the module.
func (m Module) Resource(mode ResourceMode, typeName string, name string) ConfigResource {
	return ConfigResource{
		Module: m,
		Resource: Resource{
			Mode: mode,
			Type: typeName,
			Name: name,
		},
	}
}

// Absolute produces the address for the receiver within a specific module instance.
func (r ConfigResource) Absolute(module ModuleInstance) AbsResource {
	return AbsResource{
		Module:   module,
		Resource: r.Resource,
	}
}

// TargetContains implements Targetable by returning true if the given other
// address is either equal to the receiver or is an instance of the
// receiver.
func (r ConfigResource) TargetContains(other Targetable) bool {
	switch to := other.(type) {
	case ConfigResource:
		// We'll use our stringification as a cheat-ish way to test for equality.
		return to.String() == r.String()
	case AbsResource:
		return r.TargetContains(to.Config())
	case AbsResourceInstance:
		return r.TargetContains(to.ContainingResource())
	default:
		return false
	}
}

func (r ConfigResource) AddrType() TargetableAddrType {
	return ConfigResourceAddrType
}

func (r ConfigResource) String() string {
	if len(r.Module) == 0 {
		return r.Resource.String()
	}
	return fmt.Sprintf("%s.%s", r.Module.String(), r.Resource.String())
}

func (r ConfigResource) Equal(o ConfigResource) bool {
	return r.Module.Equal(o.Module) && r.Resource.Equal(o.Resource)
}

func (r ConfigResource) UniqueKey() UniqueKey {
	return configResourceKey(r.String())
}

func (r ConfigResource) configMoveableSigil() {
	// ConfigResource is moveable
}

func (r ConfigResource) configCheckableSigil() {
	// ConfigResource represents a configuration object that declares checkable objects
}

func (v ConfigResource) CheckableKind() CheckableKind {
	return CheckableResource
}

type configResourceKey string

func (k configResourceKey) uniqueKeySigil() {}

// ResourceMode defines which lifecycle applies to a given resource. Each
// resource lifecycle has a slightly different address format.
type ResourceMode rune

//go:generate go run golang.org/x/tools/cmd/stringer -type ResourceMode

const (
	// InvalidResourceMode is the zero value of ResourceMode and is not
	// a valid resource mode.
	InvalidResourceMode ResourceMode = 0

	// ManagedResourceMode indicates a managed resource, as defined by
	// "resource" blocks in configuration.
	ManagedResourceMode ResourceMode = 'M'

	// DataResourceMode indicates a data resource, as defined by
	// "data" blocks in configuration.
	DataResourceMode ResourceMode = 'D'
)
