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

package configload

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"sort"
	"time"

	version "github.com/hashicorp/go-version"
	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/terraform/internal/configs"
	"github.com/hashicorp/terraform/internal/modsdir"
	"github.com/spf13/afero"
)

// LoadConfigWithSnapshot is a variant of LoadConfig that also simultaneously
// creates an in-memory snapshot of the configuration files used, which can
// be later used to create a loader that may read only from this snapshot.
func (l *Loader) LoadConfigWithSnapshot(rootDir string) (*configs.Config, *Snapshot, hcl.Diagnostics) {
	rootMod, diags := l.parser.LoadConfigDir(rootDir)
	if rootMod == nil {
		return nil, nil, diags
	}

	snap := &Snapshot{
		Modules: map[string]*SnapshotModule{},
	}
	walker := l.makeModuleWalkerSnapshot(snap)
	cfg, cDiags := configs.BuildConfig(rootMod, walker)
	diags = append(diags, cDiags...)

	addDiags := l.addModuleToSnapshot(snap, "", rootDir, "", nil)
	diags = append(diags, addDiags...)

	return cfg, snap, diags
}

// NewLoaderFromSnapshot creates a Loader that reads files only from the
// given snapshot.
//
// A snapshot-based loader cannot install modules, so calling InstallModules
// on the return value will cause a panic.
//
// A snapshot-based loader also has access only to configuration files. Its
// underlying parser does not have access to other files in the native
// filesystem, such as values files. For those, either use a normal loader
// (created by NewLoader) or use the configs.Parser API directly.
func NewLoaderFromSnapshot(snap *Snapshot) *Loader {
	fs := snapshotFS{snap}
	parser := configs.NewParser(fs)

	ret := &Loader{
		parser: parser,
		modules: moduleMgr{
			FS:         afero.Afero{Fs: fs},
			CanInstall: false,
			manifest:   snap.moduleManifest(),
		},
	}

	return ret
}

// Snapshot is an in-memory representation of the source files from a
// configuration, which can be used as an alternative configurations source
// for a loader with NewLoaderFromSnapshot.
//
// The primary purpose of a Snapshot is to build the configuration portion
// of a plan file (see ../../plans/planfile) so that it can later be reloaded
// and used to recover the exact configuration that the plan was built from.
type Snapshot struct {
	// Modules is a map from opaque module keys (suitable for use as directory
	// names on all supported operating systems) to the snapshot information
	// about each module.
	Modules map[string]*SnapshotModule
}

// NewEmptySnapshot constructs and returns a snapshot containing only an empty
// root module. This is not useful for anything except placeholders in tests.
func NewEmptySnapshot() *Snapshot {
	return &Snapshot{
		Modules: map[string]*SnapshotModule{
			"": &SnapshotModule{
				Files: map[string][]byte{},
			},
		},
	}
}

// SnapshotModule represents a single module within a Snapshot.
type SnapshotModule struct {
	// Dir is the path, relative to the root directory given when the
	// snapshot was created, where the module appears in the snapshot's
	// virtual filesystem.
	Dir string

	// Files is a map from each configuration file filename for the
	// module to a raw byte representation of the source file contents.
	Files map[string][]byte

	// SourceAddr is the source address given for this module in configuration.
	SourceAddr string `json:"Source"`

	// Version is the version of the module that is installed, or nil if
	// the module is installed from a source that does not support versions.
	Version *version.Version `json:"-"`
}

// moduleManifest constructs a module manifest based on the contents of
// the receiving snapshot.
func (s *Snapshot) moduleManifest() modsdir.Manifest {
	ret := make(modsdir.Manifest)

	for k, modSnap := range s.Modules {
		ret[k] = modsdir.Record{
			Key:        k,
			Dir:        modSnap.Dir,
			SourceAddr: modSnap.SourceAddr,
			Version:    modSnap.Version,
		}
	}

	return ret
}

// makeModuleWalkerSnapshot creates a configs.ModuleWalker that will exhibit
// the same lookup behaviors as l.moduleWalkerLoad but will additionally write
// source files from the referenced modules into the given snapshot.
func (l *Loader) makeModuleWalkerSnapshot(snap *Snapshot) configs.ModuleWalker {
	return configs.ModuleWalkerFunc(
		func(req *configs.ModuleRequest) (*configs.Module, *version.Version, hcl.Diagnostics) {
			mod, v, diags := l.moduleWalkerLoad(req)
			if diags.HasErrors() {
				return mod, v, diags
			}

			key := l.modules.manifest.ModuleKey(req.Path)
			record, exists := l.modules.manifest[key]

			if !exists {
				// Should never happen, since otherwise moduleWalkerLoader would've
				// returned an error and we would've returned already.
				panic(fmt.Sprintf("module %s is not present in manifest", key))
			}

			addDiags := l.addModuleToSnapshot(snap, key, record.Dir, record.SourceAddr, record.Version)
			diags = append(diags, addDiags...)

			return mod, v, diags
		},
	)
}

func (l *Loader) addModuleToSnapshot(snap *Snapshot, key string, dir string, sourceAddr string, v *version.Version) hcl.Diagnostics {
	var diags hcl.Diagnostics

	primaryFiles, overrideFiles, moreDiags := l.parser.ConfigDirFiles(dir)
	if moreDiags.HasErrors() {
		// Any diagnostics we get here should be already present
		// in diags, so it's weird if we get here but we'll allow it
		// and return a general error message in that case.
		diags = append(diags, &hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Failed to read directory for module",
			Detail:   fmt.Sprintf("The source directory %s could not be read", dir),
		})
		return diags
	}

	snapMod := &SnapshotModule{
		Dir:        dir,
		Files:      map[string][]byte{},
		SourceAddr: sourceAddr,
		Version:    v,
	}

	files := make([]string, 0, len(primaryFiles)+len(overrideFiles))
	files = append(files, primaryFiles...)
	files = append(files, overrideFiles...)
	sources := l.Sources() // should be populated with all the files we need by now
	for _, filePath := range files {
		filename := filepath.Base(filePath)
		src, exists := sources[filePath]
		if !exists {
			diags = append(diags, &hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  "Missing source file for snapshot",
				Detail:   fmt.Sprintf("The source code for file %s could not be found to produce a configuration snapshot.", filePath),
			})
			continue
		}
		snapMod.Files[filepath.Clean(filename)] = src
	}

	snap.Modules[key] = snapMod

	return diags
}

// snapshotFS is an implementation of afero.Fs that reads from a snapshot.
//
// This is not intended as a general-purpose filesystem implementation. Instead,
// it just supports the minimal functionality required to support the
// configuration loader and parser as an implementation detail of creating
// a loader from a snapshot.
type snapshotFS struct {
	snap *Snapshot
}

var _ afero.Fs = snapshotFS{}

func (fs snapshotFS) Create(name string) (afero.File, error) {
	return nil, fmt.Errorf("cannot create file inside configuration snapshot")
}

func (fs snapshotFS) Mkdir(name string, perm os.FileMode) error {
	return fmt.Errorf("cannot create directory inside configuration snapshot")
}

func (fs snapshotFS) MkdirAll(name string, perm os.FileMode) error {
	return fmt.Errorf("cannot create directories inside configuration snapshot")
}

func (fs snapshotFS) Open(name string) (afero.File, error) {

	// Our "filesystem" is sparsely populated only with the directories
	// mentioned by modules in our snapshot, so the high-level process
	// for opening a file is:
	// - Find the module snapshot corresponding to the containing directory
	// - Find the file within that snapshot
	// - Wrap the resulting byte slice in a snapshotFile to return
	//
	// The other possibility handled here is if the given name is for the
	// module directory itself, in which case we'll return a snapshotDir
	// instead.
	//
	// This function doesn't try to be incredibly robust in supporting
	// different permutations of paths, etc because in practice we only
	// need to support the path forms that our own loader and parser will
	// generate.

	dir := filepath.Dir(name)
	fn := filepath.Base(name)
	directDir := filepath.Clean(name)

	// First we'll check to see if this is an exact path for a module directory.
	// We need to do this first (rather than as part of the next loop below)
	// because a module in a child directory of another module can otherwise
	// appear to be a file in that parent directory.
	for _, candidate := range fs.snap.Modules {
		modDir := filepath.Clean(candidate.Dir)
		if modDir == directDir {
			// We've matched the module directory itself
			filenames := make([]string, 0, len(candidate.Files))
			for n := range candidate.Files {
				filenames = append(filenames, n)
			}
			sort.Strings(filenames)
			return &snapshotDir{
				filenames: filenames,
			}, nil
		}
	}

	// If we get here then the given path isn't a module directory exactly, so
	// we'll treat it as a file path and try to find a module directory it
	// could be located in.
	var modSnap *SnapshotModule
	for _, candidate := range fs.snap.Modules {
		modDir := filepath.Clean(candidate.Dir)
		if modDir == dir {
			modSnap = candidate
			break
		}
	}
	if modSnap == nil {
		return nil, os.ErrNotExist
	}

	src, exists := modSnap.Files[fn]
	if !exists {
		return nil, os.ErrNotExist
	}

	return &snapshotFile{
		src: src,
	}, nil
}

func (fs snapshotFS) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) {
	return fs.Open(name)
}

func (fs snapshotFS) Remove(name string) error {
	return fmt.Errorf("cannot remove file inside configuration snapshot")
}

func (fs snapshotFS) RemoveAll(path string) error {
	return fmt.Errorf("cannot remove files inside configuration snapshot")
}

func (fs snapshotFS) Rename(old, new string) error {
	return fmt.Errorf("cannot rename file inside configuration snapshot")
}

func (fs snapshotFS) Stat(name string) (os.FileInfo, error) {
	f, err := fs.Open(name)
	if err != nil {
		return nil, err
	}
	_, isDir := f.(*snapshotDir)
	return snapshotFileInfo{
		name:  filepath.Base(name),
		isDir: isDir,
	}, nil
}

func (fs snapshotFS) Name() string {
	return "ConfigSnapshotFS"
}

func (fs snapshotFS) Chmod(name string, mode os.FileMode) error {
	return fmt.Errorf("cannot set file mode inside configuration snapshot")
}

func (fs snapshotFS) Chtimes(name string, atime, mtime time.Time) error {
	return fmt.Errorf("cannot set file times inside configuration snapshot")
}

type snapshotFile struct {
	snapshotFileStub
	src []byte
	at  int64
}

var _ afero.File = (*snapshotFile)(nil)

func (f *snapshotFile) Read(p []byte) (n int, err error) {
	if len(p) > 0 && f.at == int64(len(f.src)) {
		return 0, io.EOF
	}
	if f.at > int64(len(f.src)) {
		return 0, io.ErrUnexpectedEOF
	}
	if int64(len(f.src))-f.at >= int64(len(p)) {
		n = len(p)
	} else {
		n = int(int64(len(f.src)) - f.at)
	}
	copy(p, f.src[f.at:f.at+int64(n)])
	f.at += int64(n)
	return
}

func (f *snapshotFile) ReadAt(p []byte, off int64) (n int, err error) {
	f.at = off
	return f.Read(p)
}

func (f *snapshotFile) Seek(offset int64, whence int) (int64, error) {
	switch whence {
	case 0:
		f.at = offset
	case 1:
		f.at += offset
	case 2:
		f.at = int64(len(f.src)) + offset
	}
	return f.at, nil
}

type snapshotDir struct {
	snapshotFileStub
	filenames []string
	at        int
}

var _ afero.File = (*snapshotDir)(nil)

func (f *snapshotDir) Readdir(count int) ([]os.FileInfo, error) {
	names, err := f.Readdirnames(count)
	if err != nil {
		return nil, err
	}
	ret := make([]os.FileInfo, len(names))
	for i, name := range names {
		ret[i] = snapshotFileInfo{
			name:  name,
			isDir: false,
		}
	}
	return ret, nil
}

func (f *snapshotDir) Readdirnames(count int) ([]string, error) {
	var outLen int
	names := f.filenames[f.at:]
	if count > 0 {
		if len(names) < count {
			outLen = len(names)
		} else {
			outLen = count
		}
		if len(names) == 0 {
			return nil, io.EOF
		}
	} else {
		outLen = len(names)
	}
	f.at += outLen

	return names[:outLen], nil
}

// snapshotFileInfo is a minimal implementation of os.FileInfo to support our
// virtual filesystem from snapshots.
type snapshotFileInfo struct {
	name  string
	isDir bool
}

var _ os.FileInfo = snapshotFileInfo{}

func (fi snapshotFileInfo) Name() string {
	return fi.name
}

func (fi snapshotFileInfo) Size() int64 {
	// In practice, our parser and loader never call Size
	return -1
}

func (fi snapshotFileInfo) Mode() os.FileMode {
	return os.ModePerm
}

func (fi snapshotFileInfo) ModTime() time.Time {
	return time.Now()
}

func (fi snapshotFileInfo) IsDir() bool {
	return fi.isDir
}

func (fi snapshotFileInfo) Sys() interface{} {
	return nil
}

type snapshotFileStub struct{}

func (f snapshotFileStub) Close() error {
	return nil
}

func (f snapshotFileStub) Read(p []byte) (n int, err error) {
	return 0, fmt.Errorf("cannot read")
}

func (f snapshotFileStub) ReadAt(p []byte, off int64) (n int, err error) {
	return 0, fmt.Errorf("cannot read")
}

func (f snapshotFileStub) Seek(offset int64, whence int) (int64, error) {
	return 0, fmt.Errorf("cannot seek")
}

func (f snapshotFileStub) Write(p []byte) (n int, err error) {
	return f.WriteAt(p, 0)
}

func (f snapshotFileStub) WriteAt(p []byte, off int64) (n int, err error) {
	return 0, fmt.Errorf("cannot write to file in snapshot")
}

func (f snapshotFileStub) WriteString(s string) (n int, err error) {
	return 0, fmt.Errorf("cannot write to file in snapshot")
}

func (f snapshotFileStub) Name() string {
	// in practice, the loader and parser never use this
	return "<unimplemented>"
}

func (f snapshotFileStub) Readdir(count int) ([]os.FileInfo, error) {
	return nil, fmt.Errorf("cannot use Readdir on a file")
}

func (f snapshotFileStub) Readdirnames(count int) ([]string, error) {
	return nil, fmt.Errorf("cannot use Readdir on a file")
}

func (f snapshotFileStub) Stat() (os.FileInfo, error) {
	return nil, fmt.Errorf("cannot stat")
}

func (f snapshotFileStub) Sync() error {
	return nil
}

func (f snapshotFileStub) Truncate(size int64) error {
	return fmt.Errorf("cannot write to file in snapshot")
}
