// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

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)
}
