package planfile

import (
	"archive/zip"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"path"
	"sort"
	"strings"
	"time"

	version "github.com/hashicorp/go-version"
	"github.com/hashicorp/terraform/internal/configs/configload"
)

const configSnapshotPrefix = "tfconfig/"
const configSnapshotManifestFile = configSnapshotPrefix + "modules.json"
const configSnapshotModulePrefix = configSnapshotPrefix + "m-"

type configSnapshotModuleRecord struct {
	Key        string `json:"Key"`
	SourceAddr string `json:"Source,omitempty"`
	VersionStr string `json:"Version,omitempty"`
	Dir        string `json:"Dir"`
}
type configSnapshotModuleManifest []configSnapshotModuleRecord

func readConfigSnapshot(z *zip.Reader) (*configload.Snapshot, error) {
	// Errors from this function are expected to be reported with some
	// additional prefix context about them being in a config snapshot,
	// so they should not themselves refer to the config snapshot.
	// They are also generally indicative of an invalid file, and so since
	// plan files should not be hand-constructed we don't need to worry
	// about making the messages user-actionable.

	snap := &configload.Snapshot{
		Modules: map[string]*configload.SnapshotModule{},
	}
	var manifestSrc []byte

	// For processing our source files, we'll just sweep over all the files
	// and react to the one-by-one to start, and then clean up afterwards
	// when we'll presumably have found the manifest file.
	for _, file := range z.File {
		switch {

		case file.Name == configSnapshotManifestFile:
			// It's the manifest file, so we'll just read it raw into
			// manifestSrc for now and process it below.
			r, err := file.Open()
			if err != nil {
				return nil, fmt.Errorf("failed to open module manifest: %s", r)
			}
			manifestSrc, err = ioutil.ReadAll(r)
			if err != nil {
				return nil, fmt.Errorf("failed to read module manifest: %s", r)
			}

		case strings.HasPrefix(file.Name, configSnapshotModulePrefix):
			relName := file.Name[len(configSnapshotModulePrefix):]
			moduleKey, fileName := path.Split(relName)

			// moduleKey should currently have a trailing slash on it, which we
			// can use to recognize the difference between the root module
			// (just a trailing slash) and no module path at all (empty string).
			if moduleKey == "" {
				// ignore invalid config entry
				continue
			}
			moduleKey = moduleKey[:len(moduleKey)-1] // trim trailing slash

			r, err := file.Open()
			if err != nil {
				return nil, fmt.Errorf("failed to open snapshot of %s from module %q: %s", fileName, moduleKey, err)
			}
			fileSrc, err := ioutil.ReadAll(r)
			if err != nil {
				return nil, fmt.Errorf("failed to read snapshot of %s from module %q: %s", fileName, moduleKey, err)
			}

			if _, exists := snap.Modules[moduleKey]; !exists {
				snap.Modules[moduleKey] = &configload.SnapshotModule{
					Files: map[string][]byte{},
					// Will fill in everything else afterwards, when we
					// process the manifest.
				}
			}
			snap.Modules[moduleKey].Files[fileName] = fileSrc
		}
	}

	if manifestSrc == nil {
		return nil, fmt.Errorf("config snapshot does not have manifest file")
	}

	var manifest configSnapshotModuleManifest
	err := json.Unmarshal(manifestSrc, &manifest)
	if err != nil {
		return nil, fmt.Errorf("invalid module manifest: %s", err)
	}

	for _, record := range manifest {
		modSnap, exists := snap.Modules[record.Key]
		if !exists {
			// We'll allow this, assuming that it's a module with no files.
			// This is still weird, since we generally reject modules with
			// no files, but we'll allow it because downstream errors will
			// catch it in that case.
			modSnap = &configload.SnapshotModule{
				Files: map[string][]byte{},
			}
			snap.Modules[record.Key] = modSnap
		}
		modSnap.SourceAddr = record.SourceAddr
		modSnap.Dir = record.Dir
		if record.VersionStr != "" {
			v, err := version.NewVersion(record.VersionStr)
			if err != nil {
				return nil, fmt.Errorf("manifest has invalid version string %q for module %q", record.VersionStr, record.Key)
			}
			modSnap.Version = v
		}
	}

	// Finally, we'll make sure we don't have any errant files for modules that
	// aren't in the manifest.
	for k := range snap.Modules {
		found := false
		for _, record := range manifest {
			if record.Key == k {
				found = true
				break
			}
		}
		if !found {
			return nil, fmt.Errorf("found files for module %q that isn't recorded in the manifest", k)
		}
	}

	return snap, nil
}

// writeConfigSnapshot adds to the given zip.Writer one or more files
// representing the given snapshot.
//
// This file creates new files in the writer, so any already-open writer
// for the file will be invalidated by this call. The writer remains open
// when this function returns.
func writeConfigSnapshot(snap *configload.Snapshot, z *zip.Writer) error {
	// Errors from this function are expected to be reported with some
	// additional prefix context about them being in a config snapshot,
	// so they should not themselves refer to the config snapshot.
	// They are also indicative of a bug in the caller, so they do not
	// need to be user-actionable.

	var manifest configSnapshotModuleManifest
	keys := make([]string, 0, len(snap.Modules))
	for k := range snap.Modules {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	// We'll re-use this fileheader for each Create we do below.

	for _, k := range keys {
		snapMod := snap.Modules[k]
		record := configSnapshotModuleRecord{
			Dir:        snapMod.Dir,
			Key:        k,
			SourceAddr: snapMod.SourceAddr,
		}
		if snapMod.Version != nil {
			record.VersionStr = snapMod.Version.String()
		}
		manifest = append(manifest, record)

		pathPrefix := fmt.Sprintf("%s%s/", configSnapshotModulePrefix, k)
		for filename, src := range snapMod.Files {
			zh := &zip.FileHeader{
				Name:     pathPrefix + filename,
				Method:   zip.Deflate,
				Modified: time.Now(),
			}
			w, err := z.CreateHeader(zh)
			if err != nil {
				return fmt.Errorf("failed to create snapshot of %s from module %q: %s", zh.Name, k, err)
			}
			_, err = w.Write(src)
			if err != nil {
				return fmt.Errorf("failed to write snapshot of %s from module %q: %s", zh.Name, k, err)
			}
		}
	}

	// Now we'll write our manifest
	{
		zh := &zip.FileHeader{
			Name:     configSnapshotManifestFile,
			Method:   zip.Deflate,
			Modified: time.Now(),
		}
		src, err := json.MarshalIndent(manifest, "", "  ")
		if err != nil {
			return fmt.Errorf("failed to serialize module manifest: %s", err)
		}
		w, err := z.CreateHeader(zh)
		if err != nil {
			return fmt.Errorf("failed to create module manifest: %s", err)
		}
		_, err = w.Write(src)
		if err != nil {
			return fmt.Errorf("failed to write module manifest: %s", err)
		}
	}

	return nil
}
