package modsdir

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"

	version "github.com/hashicorp/go-version"

	"github.com/hashicorp/terraform/internal/addrs"
)

// Record represents some metadata about an installed module, as part
// of a ModuleManifest.
type Record struct {
	// Key is a unique identifier for this particular module, based on its
	// position within the static module tree.
	Key string `json:"Key"`

	// SourceAddr is the source address given for this module in configuration.
	// This is used only to detect if the source was changed in configuration
	// since the module was last installed, which means that the installer
	// must re-install it.
	//
	// This should always be the result of calling method String on an
	// addrs.ModuleSource value, to get a suitably-normalized result.
	SourceAddr string `json:"Source"`

	// Version is the exact version of the module, which results from parsing
	// VersionStr. nil for un-versioned modules.
	Version *version.Version `json:"-"`

	// VersionStr is the version specifier string. This is used only for
	// serialization in snapshots and should not be accessed or updated
	// by any other codepaths; use "Version" instead.
	VersionStr string `json:"Version,omitempty"`

	// Dir is the path to the local directory where the module is installed.
	Dir string `json:"Dir"`
}

// Manifest is a map used to keep track of the filesystem locations
// and other metadata about installed modules.
//
// The configuration loader refers to this, while the module installer updates
// it to reflect any changes to the installed modules.
type Manifest map[string]Record

func (m Manifest) ModuleKey(path addrs.Module) string {
	if len(path) == 0 {
		return ""
	}
	return strings.Join([]string(path), ".")

}

// manifestSnapshotFile is an internal struct used only to assist in our JSON
// serialization of manifest snapshots. It should not be used for any other
// purpose.
type manifestSnapshotFile struct {
	Records []Record `json:"Modules"`
}

func ReadManifestSnapshot(r io.Reader) (Manifest, error) {
	src, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}

	if len(src) == 0 {
		// This should never happen, but we'll tolerate it as if it were
		// a valid empty JSON object.
		return make(Manifest), nil
	}

	var read manifestSnapshotFile
	err = json.Unmarshal(src, &read)
	if err != nil {
		return nil, fmt.Errorf("error unmarshalling snapshot: %v", err)
	}
	new := make(Manifest)
	for _, record := range read.Records {
		if record.VersionStr != "" {
			record.Version, err = version.NewVersion(record.VersionStr)
			if err != nil {
				return nil, fmt.Errorf("invalid version %q for %s: %s", record.VersionStr, record.Key, err)
			}
		}

		// Historically we didn't normalize the module source addresses when
		// writing them into the manifest, and so we'll make a best effort
		// to normalize them back in on read so that we can just gracefully
		// upgrade on the next "terraform init".
		if record.SourceAddr != "" {
			if addr, err := addrs.ParseModuleSource(record.SourceAddr); err == nil {
				// This is a best effort sort of thing. If the source
				// address isn't valid then we'll just leave it as-is
				// and let another component detect that downstream,
				// to preserve the old behavior in that case.
				record.SourceAddr = addr.String()
			}
		}

		// Ensure Windows is using the proper modules path format after
		// reading the modules manifest Dir records
		record.Dir = filepath.FromSlash(record.Dir)

		if _, exists := new[record.Key]; exists {
			// This should never happen in any valid file, so we'll catch it
			// and report it to avoid confusing/undefined behavior if the
			// snapshot file was edited incorrectly outside of Terraform.
			return nil, fmt.Errorf("snapshot file contains two records for path %s", record.Key)
		}
		new[record.Key] = record
	}
	return new, nil
}

func ReadManifestSnapshotForDir(dir string) (Manifest, error) {
	fn := filepath.Join(dir, ManifestSnapshotFilename)
	r, err := os.Open(fn)
	if err != nil {
		if os.IsNotExist(err) {
			return make(Manifest), nil // missing file is okay and treated as empty
		}
		return nil, err
	}
	return ReadManifestSnapshot(r)
}

func (m Manifest) WriteSnapshot(w io.Writer) error {
	var write manifestSnapshotFile

	for _, record := range m {
		// Make sure VersionStr is in sync with Version, since we encourage
		// callers to manipulate Version and ignore VersionStr.
		if record.Version != nil {
			record.VersionStr = record.Version.String()
		} else {
			record.VersionStr = ""
		}

		// Ensure Dir is written in a format that can be read by Linux and
		// Windows nodes for remote and apply compatibility
		record.Dir = filepath.ToSlash(record.Dir)
		write.Records = append(write.Records, record)
	}

	src, err := json.Marshal(write)
	if err != nil {
		return err
	}

	_, err = w.Write(src)
	return err
}

func (m Manifest) WriteSnapshotToDir(dir string) error {
	fn := filepath.Join(dir, ManifestSnapshotFilename)
	log.Printf("[TRACE] modsdir: writing modules manifest to %s", fn)
	w, err := os.Create(fn)
	if err != nil {
		return err
	}
	return m.WriteSnapshot(w)
}
