package modsdir

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"sort"
	"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

	var keys []string
	for k := range m {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		record := m[k]

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