package jsonconfig

import (
	"encoding/json"
	"fmt"
	"sort"

	"github.com/zclconf/go-cty/cty"
	ctyjson "github.com/zclconf/go-cty/cty/json"

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

// Config represents the complete configuration source
type config struct {
	ProviderConfigs map[string]providerConfig `json:"provider_config,omitempty"`
	RootModule      module                    `json:"root_module,omitempty"`
}

// ProviderConfig describes all of the provider configurations throughout the
// configuration tree, flattened into a single map for convenience since
// provider configurations are the one concept in Terraform that can span across
// module boundaries.
type providerConfig struct {
	Name              string                 `json:"name,omitempty"`
	FullName          string                 `json:"full_name,omitempty"`
	Alias             string                 `json:"alias,omitempty"`
	VersionConstraint string                 `json:"version_constraint,omitempty"`
	ModuleAddress     string                 `json:"module_address,omitempty"`
	Expressions       map[string]interface{} `json:"expressions,omitempty"`
	parentKey         string
}

type module struct {
	Outputs map[string]output `json:"outputs,omitempty"`
	// Resources are sorted in a user-friendly order that is undefined at this
	// time, but consistent.
	Resources   []resource            `json:"resources,omitempty"`
	ModuleCalls map[string]moduleCall `json:"module_calls,omitempty"`
	Variables   variables             `json:"variables,omitempty"`
}

type moduleCall struct {
	Source            string                 `json:"source,omitempty"`
	Expressions       map[string]interface{} `json:"expressions,omitempty"`
	CountExpression   *expression            `json:"count_expression,omitempty"`
	ForEachExpression *expression            `json:"for_each_expression,omitempty"`
	Module            module                 `json:"module,omitempty"`
	VersionConstraint string                 `json:"version_constraint,omitempty"`
	DependsOn         []string               `json:"depends_on,omitempty"`
}

// variables is the JSON representation of the variables provided to the current
// plan.
type variables map[string]*variable

type variable struct {
	Default     json.RawMessage `json:"default,omitempty"`
	Description string          `json:"description,omitempty"`
	Sensitive   bool            `json:"sensitive,omitempty"`
}

// Resource is the representation of a resource in the config
type resource struct {
	// Address is the absolute resource address
	Address string `json:"address,omitempty"`

	// Mode can be "managed" or "data"
	Mode string `json:"mode,omitempty"`

	Type string `json:"type,omitempty"`
	Name string `json:"name,omitempty"`

	// ProviderConfigKey is the key into "provider_configs" (shown above) for
	// the provider configuration that this resource is associated with.
	//
	// NOTE: If a given resource is in a ModuleCall, and the provider was
	// configured outside of the module (in a higher level configuration file),
	// the ProviderConfigKey will not match a key in the ProviderConfigs map.
	ProviderConfigKey string `json:"provider_config_key,omitempty"`

	// Provisioners is an optional field which describes any provisioners.
	// Connection info will not be included here.
	Provisioners []provisioner `json:"provisioners,omitempty"`

	// Expressions" describes the resource-type-specific  content of the
	// configuration block.
	Expressions map[string]interface{} `json:"expressions,omitempty"`

	// SchemaVersion indicates which version of the resource type schema the
	// "values" property conforms to.
	SchemaVersion uint64 `json:"schema_version"`

	// CountExpression and ForEachExpression describe the expressions given for
	// the corresponding meta-arguments in the resource configuration block.
	// These are omitted if the corresponding argument isn't set.
	CountExpression   *expression `json:"count_expression,omitempty"`
	ForEachExpression *expression `json:"for_each_expression,omitempty"`

	DependsOn []string `json:"depends_on,omitempty"`
}

type output struct {
	Sensitive   bool       `json:"sensitive,omitempty"`
	Expression  expression `json:"expression,omitempty"`
	DependsOn   []string   `json:"depends_on,omitempty"`
	Description string     `json:"description,omitempty"`
}

type provisioner struct {
	Type        string                 `json:"type,omitempty"`
	Expressions map[string]interface{} `json:"expressions,omitempty"`
}

// Marshal returns the json encoding of terraform configuration.
func Marshal(c *configs.Config, schemas *terraform.Schemas) ([]byte, error) {
	var output config

	pcs := make(map[string]providerConfig)
	marshalProviderConfigs(c, schemas, pcs)

	rootModule, err := marshalModule(c, schemas, "")
	if err != nil {
		return nil, err
	}
	output.RootModule = rootModule

	normalizeModuleProviderKeys(&rootModule, pcs)

	for name, pc := range pcs {
		if pc.parentKey != "" {
			delete(pcs, name)
		}
	}
	output.ProviderConfigs = pcs

	ret, err := json.Marshal(output)
	return ret, err
}

func marshalProviderConfigs(
	c *configs.Config,
	schemas *terraform.Schemas,
	m map[string]providerConfig,
) {
	if c == nil {
		return
	}

	// We want to determine only the provider requirements from this module,
	// ignoring any descendants.  Disregard any diagnostics when determining
	// requirements because we want this marshalling to succeed even if there
	// are invalid constraints.
	reqs, _ := c.ProviderRequirementsShallow()

	// Add an entry for each provider configuration block in the module.
	for k, pc := range c.Module.ProviderConfigs {
		providerFqn := c.ProviderForConfigAddr(addrs.LocalProviderConfig{LocalName: pc.Name})
		schema := schemas.ProviderConfig(providerFqn)

		p := providerConfig{
			Name:          pc.Name,
			FullName:      providerFqn.String(),
			Alias:         pc.Alias,
			ModuleAddress: c.Path.String(),
			Expressions:   marshalExpressions(pc.Config, schema),
		}

		// Store the fully resolved provider version constraint, rather than
		// using the version argument in the configuration block. This is both
		// future proof (for when we finish the deprecation of the provider config
		// version argument) and more accurate (as it reflects the full set of
		// constraints, in case there are multiple).
		if vc, ok := reqs[providerFqn]; ok {
			p.VersionConstraint = getproviders.VersionConstraintsString(vc)
		}

		key := opaqueProviderKey(k, c.Path.String())

		m[key] = p
	}

	// Ensure that any required providers with no associated configuration
	// block are included in the set.
	for k, pr := range c.Module.ProviderRequirements.RequiredProviders {
		// If a provider has aliases defined, process those first.
		for _, alias := range pr.Aliases {
			// If there exists a value for this provider, we have nothing to add
			// to it, so skip.
			key := opaqueProviderKey(alias.StringCompact(), c.Path.String())
			if _, exists := m[key]; exists {
				continue
			}
			// Given no provider configuration block exists, the only fields we can
			// fill here are the local name, FQN, module address, and version
			// constraints.
			p := providerConfig{
				Name:          pr.Name,
				FullName:      pr.Type.String(),
				ModuleAddress: c.Path.String(),
			}

			if vc, ok := reqs[pr.Type]; ok {
				p.VersionConstraint = getproviders.VersionConstraintsString(vc)
			}

			m[key] = p
		}

		// If there exists a value for this provider, we have nothing to add
		// to it, so skip.
		key := opaqueProviderKey(k, c.Path.String())
		if _, exists := m[key]; exists {
			continue
		}

		// Given no provider configuration block exists, the only fields we can
		// fill here are the local name, module address, and version
		// constraints.
		p := providerConfig{
			Name:          pr.Name,
			FullName:      pr.Type.String(),
			ModuleAddress: c.Path.String(),
		}

		if vc, ok := reqs[pr.Type]; ok {
			p.VersionConstraint = getproviders.VersionConstraintsString(vc)
		}

		if c.Parent != nil {
			parentKey := opaqueProviderKey(pr.Name, c.Parent.Path.String())
			p.parentKey = findSourceProviderKey(parentKey, p.FullName, m)
		}

		m[key] = p
	}

	// Providers could be implicitly created or inherited from the parent module
	// when no requirements and configuration block defined.
	for req := range reqs {
		// Only default providers could implicitly exist,
		// so the provider name must be same as the provider type.
		key := opaqueProviderKey(req.Type, c.Path.String())
		if _, exists := m[key]; exists {
			continue
		}

		p := providerConfig{
			Name:          req.Type,
			FullName:      req.String(),
			ModuleAddress: c.Path.String(),
		}

		// In child modules, providers defined in the parent module can be implicitly used.
		if c.Parent != nil {
			parentKey := opaqueProviderKey(req.Type, c.Parent.Path.String())
			p.parentKey = findSourceProviderKey(parentKey, p.FullName, m)
		}

		m[key] = p
	}

	// Must also visit our child modules, recursively.
	for name, mc := range c.Module.ModuleCalls {
		// Keys in c.Children are guaranteed to match those in c.Module.ModuleCalls
		cc := c.Children[name]

		// Add provider config map entries for passed provider configs,
		// pointing at the passed configuration
		for _, ppc := range mc.Providers {
			// These provider names include aliases, if set
			moduleProviderName := ppc.InChild.String()
			parentProviderName := ppc.InParent.String()

			// Look up the provider FQN from the module context, using the non-aliased local name
			providerFqn := cc.ProviderForConfigAddr(addrs.LocalProviderConfig{LocalName: ppc.InChild.Name})

			// The presence of passed provider configs means that we cannot have
			// any configuration expressions or version constraints here
			p := providerConfig{
				Name:          moduleProviderName,
				FullName:      providerFqn.String(),
				ModuleAddress: cc.Path.String(),
			}

			key := opaqueProviderKey(moduleProviderName, cc.Path.String())
			parentKey := opaqueProviderKey(parentProviderName, cc.Parent.Path.String())
			p.parentKey = findSourceProviderKey(parentKey, p.FullName, m)

			m[key] = p
		}

		// Finally, marshal any other provider configs within the called module.
		// It is safe to do this last because it is invalid to configure a
		// provider which has passed provider configs in the module call.
		marshalProviderConfigs(cc, schemas, m)
	}
}

func marshalModule(c *configs.Config, schemas *terraform.Schemas, addr string) (module, error) {
	var module module
	var rs []resource

	managedResources, err := marshalResources(c.Module.ManagedResources, schemas, addr)
	if err != nil {
		return module, err
	}
	dataResources, err := marshalResources(c.Module.DataResources, schemas, addr)
	if err != nil {
		return module, err
	}

	rs = append(managedResources, dataResources...)
	module.Resources = rs

	outputs := make(map[string]output)
	for _, v := range c.Module.Outputs {
		o := output{
			Sensitive:  v.Sensitive,
			Expression: marshalExpression(v.Expr),
		}
		if v.Description != "" {
			o.Description = v.Description
		}
		if len(v.DependsOn) > 0 {
			dependencies := make([]string, len(v.DependsOn))
			for i, d := range v.DependsOn {
				ref, diags := addrs.ParseRef(d)
				// we should not get an error here, because `terraform validate`
				// would have complained well before this point, but if we do we'll
				// silenty skip it.
				if !diags.HasErrors() {
					dependencies[i] = ref.Subject.String()
				}
			}
			o.DependsOn = dependencies
		}

		outputs[v.Name] = o
	}
	module.Outputs = outputs

	module.ModuleCalls = marshalModuleCalls(c, schemas)

	if len(c.Module.Variables) > 0 {
		vars := make(variables, len(c.Module.Variables))
		for k, v := range c.Module.Variables {
			var defaultValJSON []byte
			if v.Default == cty.NilVal {
				defaultValJSON = nil
			} else {
				defaultValJSON, err = ctyjson.Marshal(v.Default, v.Default.Type())
				if err != nil {
					return module, err
				}
			}
			vars[k] = &variable{
				Default:     defaultValJSON,
				Description: v.Description,
				Sensitive:   v.Sensitive,
			}
		}
		module.Variables = vars
	}

	return module, nil
}

func marshalModuleCalls(c *configs.Config, schemas *terraform.Schemas) map[string]moduleCall {
	ret := make(map[string]moduleCall)

	for name, mc := range c.Module.ModuleCalls {
		mcConfig := c.Children[name]
		ret[name] = marshalModuleCall(mcConfig, mc, schemas)
	}

	return ret
}

func marshalModuleCall(c *configs.Config, mc *configs.ModuleCall, schemas *terraform.Schemas) moduleCall {
	// It is possible to have a module call with a nil config.
	if c == nil {
		return moduleCall{}
	}

	ret := moduleCall{
		// We're intentionally echoing back exactly what the user entered
		// here, rather than the normalized version in SourceAddr, because
		// historically we only _had_ the raw address and thus it would be
		// a (admittedly minor) breaking change to start normalizing them
		// now, in case consumers of this data are expecting a particular
		// non-normalized syntax.
		Source:            mc.SourceAddrRaw,
		VersionConstraint: mc.Version.Required.String(),
	}
	cExp := marshalExpression(mc.Count)
	if !cExp.Empty() {
		ret.CountExpression = &cExp
	} else {
		fExp := marshalExpression(mc.ForEach)
		if !fExp.Empty() {
			ret.ForEachExpression = &fExp
		}
	}

	schema := &configschema.Block{}
	schema.Attributes = make(map[string]*configschema.Attribute)
	for _, variable := range c.Module.Variables {
		schema.Attributes[variable.Name] = &configschema.Attribute{
			Required: variable.Default == cty.NilVal,
		}
	}

	ret.Expressions = marshalExpressions(mc.Config, schema)

	module, _ := marshalModule(c, schemas, c.Path.String())

	ret.Module = module

	if len(mc.DependsOn) > 0 {
		dependencies := make([]string, len(mc.DependsOn))
		for i, d := range mc.DependsOn {
			ref, diags := addrs.ParseRef(d)
			// we should not get an error here, because `terraform validate`
			// would have complained well before this point, but if we do we'll
			// silenty skip it.
			if !diags.HasErrors() {
				dependencies[i] = ref.Subject.String()
			}
		}
		ret.DependsOn = dependencies
	}

	return ret
}

func marshalResources(resources map[string]*configs.Resource, schemas *terraform.Schemas, moduleAddr string) ([]resource, error) {
	var rs []resource
	for _, v := range resources {
		providerConfigKey := opaqueProviderKey(v.ProviderConfigAddr().StringCompact(), moduleAddr)
		r := resource{
			Address:           v.Addr().String(),
			Type:              v.Type,
			Name:              v.Name,
			ProviderConfigKey: providerConfigKey,
		}

		switch v.Mode {
		case addrs.ManagedResourceMode:
			r.Mode = "managed"
		case addrs.DataResourceMode:
			r.Mode = "data"
		default:
			return rs, fmt.Errorf("resource %s has an unsupported mode %s", r.Address, v.Mode.String())
		}

		cExp := marshalExpression(v.Count)
		if !cExp.Empty() {
			r.CountExpression = &cExp
		} else {
			fExp := marshalExpression(v.ForEach)
			if !fExp.Empty() {
				r.ForEachExpression = &fExp
			}
		}

		schema, schemaVer := schemas.ResourceTypeConfig(
			v.Provider,
			v.Mode,
			v.Type,
		)
		if schema == nil {
			return nil, fmt.Errorf("no schema found for %s (in provider %s)", v.Addr().String(), v.Provider)
		}
		r.SchemaVersion = schemaVer

		r.Expressions = marshalExpressions(v.Config, schema)

		// Managed is populated only for Mode = addrs.ManagedResourceMode
		if v.Managed != nil && len(v.Managed.Provisioners) > 0 {
			var provisioners []provisioner
			for _, p := range v.Managed.Provisioners {
				schema := schemas.ProvisionerConfig(p.Type)
				prov := provisioner{
					Type:        p.Type,
					Expressions: marshalExpressions(p.Config, schema),
				}
				provisioners = append(provisioners, prov)
			}
			r.Provisioners = provisioners
		}

		if len(v.DependsOn) > 0 {
			dependencies := make([]string, len(v.DependsOn))
			for i, d := range v.DependsOn {
				ref, diags := addrs.ParseRef(d)
				// we should not get an error here, because `terraform validate`
				// would have complained well before this point, but if we do we'll
				// silenty skip it.
				if !diags.HasErrors() {
					dependencies[i] = ref.Subject.String()
				}
			}
			r.DependsOn = dependencies
		}

		rs = append(rs, r)
	}
	sort.Slice(rs, func(i, j int) bool {
		return rs[i].Address < rs[j].Address
	})
	return rs, nil
}

// Flatten all resource provider keys in a module and its descendents, such
// that any resources from providers using a configuration passed through the
// module call have a direct refernce to that provider configuration.
func normalizeModuleProviderKeys(m *module, pcs map[string]providerConfig) {
	for i, r := range m.Resources {
		if pc, exists := pcs[r.ProviderConfigKey]; exists {
			if _, hasParent := pcs[pc.parentKey]; hasParent {
				m.Resources[i].ProviderConfigKey = pc.parentKey
			}
		}
	}

	for _, mc := range m.ModuleCalls {
		normalizeModuleProviderKeys(&mc.Module, pcs)
	}
}

// opaqueProviderKey generates a unique absProviderConfig-like string from the module
// address and provider
func opaqueProviderKey(provider string, addr string) (key string) {
	key = provider
	if addr != "" {
		key = fmt.Sprintf("%s:%s", addr, provider)
	}
	return key
}

// Traverse up the module call tree until we find the provider
// configuration which has no linked parent config. This is then
// the source of the configuration used in this module call, so
// we link to it directly
func findSourceProviderKey(startKey string, fullName string, m map[string]providerConfig) string {
	var parentKey string

	key := startKey
	for key != "" {
		parent, exists := m[key]
		if !exists || parent.FullName != fullName {
			break
		}

		parentKey = key
		key = parent.parentKey
	}

	return parentKey
}
