package configload

import (
	"fmt"
	"path/filepath"

	"github.com/hashicorp/terraform-svchost/disco"
	"github.com/hashicorp/terraform/internal/configs"
	"github.com/hashicorp/terraform/internal/registry"
	"github.com/spf13/afero"
)

// A Loader instance is the main entry-point for loading configurations via
// this package.
//
// It extends the general config-loading functionality in the parent package
// "configs" to support installation of modules from remote sources and
// loading full configurations using modules that were previously installed.
type Loader struct {
	// parser is used to read configuration
	parser *configs.Parser

	// modules is used to install and locate descendent modules that are
	// referenced (directly or indirectly) from the root module.
	modules moduleMgr
}

// Config is used with NewLoader to specify configuration arguments for the
// loader.
type Config struct {
	// ModulesDir is a path to a directory where descendent modules are
	// (or should be) installed. (This is usually the
	// .terraform/modules directory, in the common case where this package
	// is being loaded from the main Terraform CLI package.)
	ModulesDir string

	// Services is the service discovery client to use when locating remote
	// module registry endpoints. If this is nil then registry sources are
	// not supported, which should be true only in specialized circumstances
	// such as in tests.
	Services *disco.Disco
}

// NewLoader creates and returns a loader that reads configuration from the
// real OS filesystem.
//
// The loader has some internal state about the modules that are currently
// installed, which is read from disk as part of this function. If that
// manifest cannot be read then an error will be returned.
func NewLoader(config *Config) (*Loader, error) {
	fs := afero.NewOsFs()
	parser := configs.NewParser(fs)
	reg := registry.NewClient(config.Services, nil)

	ret := &Loader{
		parser: parser,
		modules: moduleMgr{
			FS:         afero.Afero{Fs: fs},
			CanInstall: true,
			Dir:        config.ModulesDir,
			Services:   config.Services,
			Registry:   reg,
		},
	}

	err := ret.modules.readModuleManifestSnapshot()
	if err != nil {
		return nil, fmt.Errorf("failed to read module manifest: %s", err)
	}

	return ret, nil
}

// ModulesDir returns the path to the directory where the loader will look for
// the local cache of remote module packages.
func (l *Loader) ModulesDir() string {
	return l.modules.Dir
}

// RefreshModules updates the in-memory cache of the module manifest from the
// module manifest file on disk. This is not necessary in normal use because
// module installation and configuration loading are separate steps, but it
// can be useful in tests where module installation is done as a part of
// configuration loading by a helper function.
//
// Call this function after any module installation where an existing loader
// is already alive and may be used again later.
//
// An error is returned if the manifest file cannot be read.
func (l *Loader) RefreshModules() error {
	if l == nil {
		// Nothing to do, then.
		return nil
	}
	return l.modules.readModuleManifestSnapshot()
}

// Parser returns the underlying parser for this loader.
//
// This is useful for loading other sorts of files than the module directories
// that a loader deals with, since then they will share the source code cache
// for this loader and can thus be shown as snippets in diagnostic messages.
func (l *Loader) Parser() *configs.Parser {
	return l.parser
}

// Sources returns the source code cache for the underlying parser of this
// loader. This is a shorthand for l.Parser().Sources().
func (l *Loader) Sources() map[string][]byte {
	return l.parser.Sources()
}

// IsConfigDir returns true if and only if the given directory contains at
// least one Terraform configuration file. This is a wrapper around calling
// the same method name on the loader's parser.
func (l *Loader) IsConfigDir(path string) bool {
	return l.parser.IsConfigDir(path)
}

// ImportSources writes into the receiver's source code map the given source
// code buffers.
//
// This is useful in the situation where an ancillary loader is created for
// some reason (e.g. loading config from a plan file) but the cached source
// code from that loader must be imported into the "main" loader in order
// to return source code snapshots in diagnostic messages.
//
//	loader.ImportSources(otherLoader.Sources())
func (l *Loader) ImportSources(sources map[string][]byte) {
	p := l.Parser()
	for name, src := range sources {
		p.ForceFileSource(name, src)
	}
}

// ImportSourcesFromSnapshot writes into the receiver's source code the
// source files from the given snapshot.
//
// This is similar to ImportSources but knows how to unpack and flatten a
// snapshot data structure to get the corresponding flat source file map.
func (l *Loader) ImportSourcesFromSnapshot(snap *Snapshot) {
	p := l.Parser()
	for _, m := range snap.Modules {
		baseDir := m.Dir
		for fn, src := range m.Files {
			fullPath := filepath.Join(baseDir, fn)
			p.ForceFileSource(fullPath, src)
		}
	}
}

// AllowLanguageExperiments specifies whether subsequent LoadConfig (and
// similar) calls will allow opting in to experimental language features.
//
// If this method is never called for a particular loader, the default behavior
// is to disallow language experiments.
//
// Main code should set this only for alpha or development builds. Test code
// is responsible for deciding for itself whether and how to call this
// method.
func (l *Loader) AllowLanguageExperiments(allowed bool) {
	l.parser.AllowLanguageExperiments(allowed)
}
