package earlyconfig

import (
	"fmt"
	"sort"
	"strings"

	version "github.com/hashicorp/go-version"
	"github.com/hashicorp/terraform-config-inspect/tfconfig"
	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/tfdiags"
)

// BuildConfig constructs a Config from a root module by loading all of its
// descendent modules via the given ModuleWalker.
func BuildConfig(root *tfconfig.Module, walker ModuleWalker) (*Config, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	cfg := &Config{
		Module: root,
	}
	cfg.Root = cfg // Root module is self-referential.
	cfg.Children, diags = buildChildModules(cfg, walker)
	return cfg, diags
}

func buildChildModules(parent *Config, walker ModuleWalker) (map[string]*Config, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	ret := map[string]*Config{}
	calls := parent.Module.ModuleCalls

	// We'll sort the calls by their local names so that they'll appear in a
	// predictable order in any logging that's produced during the walk.
	callNames := make([]string, 0, len(calls))
	for k := range calls {
		callNames = append(callNames, k)
	}
	sort.Strings(callNames)

	for _, callName := range callNames {
		call := calls[callName]
		path := make([]string, len(parent.Path)+1)
		copy(path, parent.Path)
		path[len(path)-1] = call.Name

		var vc version.Constraints
		haveVersionArg := false
		if strings.TrimSpace(call.Version) != "" {
			haveVersionArg = true

			var err error
			vc, err = version.NewConstraint(call.Version)
			if err != nil {
				diags = diags.Append(wrapDiagnostic(tfconfig.Diagnostic{
					Severity: tfconfig.DiagError,
					Summary:  "Invalid version constraint",
					Detail:   fmt.Sprintf("Module %q (declared at %s line %d) has invalid version constraint %q: %s.", callName, call.Pos.Filename, call.Pos.Line, call.Version, err),
				}))
				continue
			}
		}

		var sourceAddr addrs.ModuleSource
		var err error
		if haveVersionArg {
			sourceAddr, err = addrs.ParseModuleSourceRegistry(call.Source)
		} else {
			sourceAddr, err = addrs.ParseModuleSource(call.Source)
		}
		if err != nil {
			if haveVersionArg {
				diags = diags.Append(wrapDiagnostic(tfconfig.Diagnostic{
					Severity: tfconfig.DiagError,
					Summary:  "Invalid registry module source address",
					Detail:   fmt.Sprintf("Module %q (declared at %s line %d) has invalid source address %q: %s.\n\nTerraform assumed that you intended a module registry source address because you also set the argument \"version\", which applies only to registry modules.", callName, call.Pos.Filename, call.Pos.Line, call.Source, err),
				}))
			} else {
				diags = diags.Append(wrapDiagnostic(tfconfig.Diagnostic{
					Severity: tfconfig.DiagError,
					Summary:  "Invalid module source address",
					Detail:   fmt.Sprintf("Module %q (declared at %s line %d) has invalid source address %q: %s.", callName, call.Pos.Filename, call.Pos.Line, call.Source, err),
				}))
			}
			// If we didn't have a valid source address then we can't continue
			// down the module tree with this one.
			continue
		}

		req := ModuleRequest{
			Name:               call.Name,
			Path:               path,
			SourceAddr:         sourceAddr,
			VersionConstraints: vc,
			Parent:             parent,
			CallPos:            call.Pos,
		}

		mod, ver, modDiags := walker.LoadModule(&req)
		diags = append(diags, modDiags...)
		if mod == nil {
			// nil can be returned if the source address was invalid and so
			// nothing could be loaded whatsoever. LoadModule should've
			// returned at least one error diagnostic in that case.
			continue
		}

		child := &Config{
			Parent:     parent,
			Root:       parent.Root,
			Path:       path,
			Module:     mod,
			CallPos:    call.Pos,
			SourceAddr: sourceAddr,
			Version:    ver,
		}

		child.Children, modDiags = buildChildModules(child, walker)
		diags = diags.Append(modDiags)

		ret[call.Name] = child
	}

	return ret, diags
}

// ModuleRequest is used as part of the ModuleWalker interface used with
// function BuildConfig.
type ModuleRequest struct {
	// Name is the "logical name" of the module call within configuration.
	// This is provided in case the name is used as part of a storage key
	// for the module, but implementations must otherwise treat it as an
	// opaque string. It is guaranteed to have already been validated as an
	// HCL identifier and UTF-8 encoded.
	Name string

	// Path is a list of logical names that traverse from the root module to
	// this module. This can be used, for example, to form a lookup key for
	// each distinct module call in a configuration, allowing for multiple
	// calls with the same name at different points in the tree.
	Path addrs.Module

	// SourceAddr is the source address string provided by the user in
	// configuration.
	SourceAddr addrs.ModuleSource

	// VersionConstraint is the version constraint applied to the module in
	// configuration.
	VersionConstraints version.Constraints

	// Parent is the partially-constructed module tree node that the loaded
	// module will be added to. Callers may refer to any field of this
	// structure except Children, which is still under construction when
	// ModuleRequest objects are created and thus has undefined content.
	// The main reason this is provided is so that full module paths can
	// be constructed for uniqueness.
	Parent *Config

	// CallRange is the source position for the header of the "module" block
	// in configuration that prompted this request.
	CallPos tfconfig.SourcePos
}

// ModuleWalker is an interface used with BuildConfig.
type ModuleWalker interface {
	LoadModule(req *ModuleRequest) (*tfconfig.Module, *version.Version, tfdiags.Diagnostics)
}

// ModuleWalkerFunc is an implementation of ModuleWalker that directly wraps
// a callback function, for more convenient use of that interface.
type ModuleWalkerFunc func(req *ModuleRequest) (*tfconfig.Module, *version.Version, tfdiags.Diagnostics)

func (f ModuleWalkerFunc) LoadModule(req *ModuleRequest) (*tfconfig.Module, *version.Version, tfdiags.Diagnostics) {
	return f(req)
}
