package cliconfig

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

	"github.com/zclconf/go-cty/cty"
	ctyjson "github.com/zclconf/go-cty/cty/json"

	svchost "github.com/hashicorp/terraform-svchost"
	svcauth "github.com/hashicorp/terraform-svchost/auth"
	"github.com/hashicorp/terraform/internal/configs/hcl2shim"
	pluginDiscovery "github.com/hashicorp/terraform/internal/plugin/discovery"
	"github.com/hashicorp/terraform/internal/replacefile"
)

// credentialsConfigFile returns the path for the special configuration file
// that the credentials source will use when asked to save or forget credentials
// and when a "credentials helper" program is not active.
func credentialsConfigFile() (string, error) {
	configDir, err := ConfigDir()
	if err != nil {
		return "", err
	}
	return filepath.Join(configDir, "credentials.tfrc.json"), nil
}

// CredentialsSource creates and returns a service credentials source whose
// behavior depends on which "credentials" and "credentials_helper" blocks,
// if any, are present in the receiving config.
func (c *Config) CredentialsSource(helperPlugins pluginDiscovery.PluginMetaSet) (*CredentialsSource, error) {
	credentialsFilePath, err := credentialsConfigFile()
	if err != nil {
		// If we managed to load a Config object at all then we would already
		// have located this file, so this error is very unlikely.
		return nil, fmt.Errorf("can't locate credentials file: %s", err)
	}

	var helper svcauth.CredentialsSource
	var helperType string
	for givenType, givenConfig := range c.CredentialsHelpers {
		available := helperPlugins.WithName(givenType)
		if available.Count() == 0 {
			log.Printf("[ERROR] Unable to find credentials helper %q; ignoring", givenType)
			break
		}

		selected := available.Newest()

		helperSource := svcauth.HelperProgramCredentialsSource(selected.Path, givenConfig.Args...)
		helper = svcauth.CachingCredentialsSource(helperSource) // cached because external operation may be slow/expensive
		helperType = givenType

		// There should only be zero or one "credentials_helper" blocks. We
		// assume that the config was validated earlier and so we don't check
		// for extras here.
		break
	}

	return c.credentialsSource(helperType, helper, credentialsFilePath), nil
}

// EmptyCredentialsSourceForTests constructs a CredentialsSource with
// no credentials pre-loaded and which writes new credentials to a file
// at the given path.
//
// As the name suggests, this function is here only for testing and should not
// be used in normal application code.
func EmptyCredentialsSourceForTests(credentialsFilePath string) *CredentialsSource {
	cfg := &Config{}
	return cfg.credentialsSource("", nil, credentialsFilePath)
}

// credentialsSource is an internal factory for the credentials source which
// allows overriding the credentials file path, which allows setting it to
// a temporary file location when testing.
func (c *Config) credentialsSource(helperType string, helper svcauth.CredentialsSource, credentialsFilePath string) *CredentialsSource {
	configured := map[svchost.Hostname]cty.Value{}
	for userHost, creds := range c.Credentials {
		host, err := svchost.ForComparison(userHost)
		if err != nil {
			// We expect the config was already validated by the time we get
			// here, so we'll just ignore invalid hostnames.
			continue
		}

		// For now our CLI config continues to use HCL 1.0, so we'll shim it
		// over to HCL 2.0 types. In future we will hopefully migrate it to
		// HCL 2.0 instead, and so it'll be a cty.Value already.
		credsV := hcl2shim.HCL2ValueFromConfigValue(creds)
		configured[host] = credsV
	}

	writableLocal := readHostsInCredentialsFile(credentialsFilePath)
	unwritableLocal := map[svchost.Hostname]cty.Value{}
	for host, v := range configured {
		if _, exists := writableLocal[host]; !exists {
			unwritableLocal[host] = v
		}
	}

	return &CredentialsSource{
		configured:          configured,
		unwritable:          unwritableLocal,
		credentialsFilePath: credentialsFilePath,
		helper:              helper,
		helperType:          helperType,
	}
}

func collectCredentialsFromEnv() map[svchost.Hostname]string {
	const prefix = "TF_TOKEN_"

	ret := make(map[svchost.Hostname]string)
	for _, ev := range os.Environ() {
		eqIdx := strings.Index(ev, "=")
		if eqIdx < 0 {
			continue
		}
		name := ev[:eqIdx]
		value := ev[eqIdx+1:]
		if !strings.HasPrefix(name, prefix) {
			continue
		}
		rawHost := name[len(prefix):]

		// We accept double underscores in place of hyphens because hyphens are not valid
		// identifiers in most shells and are therefore hard to set.
		// This is unambiguous with replacing single underscores below because
		// hyphens are not allowed at the beginning or end of a label and therefore
		// odd numbers of underscores will not appear together in a valid variable name.
		rawHost = strings.ReplaceAll(rawHost, "__", "-")

		// We accept underscores in place of dots because dots are not valid
		// identifiers in most shells and are therefore hard to set.
		// Underscores are not valid in hostnames, so this is unambiguous for
		// valid hostnames.
		rawHost = strings.ReplaceAll(rawHost, "_", ".")

		// Because environment variables are often set indirectly by OS
		// libraries that might interfere with how they are encoded, we'll
		// be tolerant of them being given either directly as UTF-8 IDNs
		// or in Punycode form, normalizing to Punycode form here because
		// that is what the Terraform credentials helper protocol will
		// use in its requests.
		//
		// Using ForDisplay first here makes this more liberal than Terraform
		// itself would usually be in that it will tolerate pre-punycoded
		// hostnames that Terraform normally rejects in other contexts in order
		// to ensure stored hostnames are human-readable.
		dispHost := svchost.ForDisplay(rawHost)
		hostname, err := svchost.ForComparison(dispHost)
		if err != nil {
			// Ignore invalid hostnames
			continue
		}

		ret[hostname] = value
	}

	return ret
}

// hostCredentialsFromEnv returns a token credential by searching for a hostname-specific
// environment variable. The host parameter is expected to be in the "comparison" form,
// for example, hostnames containing non-ASCII characters like "café.fr"
// should be expressed as "xn--caf-dma.fr". If the variable based on the hostname is not
// defined, nil is returned.
//
// Hyphen and period characters are allowed in environment variable names, but are not valid POSIX
// variable names. However, it's still possible to set variable names with these characters using
// utilities like env or docker. Variable names may have periods translated to underscores and
// hyphens translated to double underscores in the variable name.
// For the example "café.fr", you may use the variable names "TF_TOKEN_xn____caf__dma_fr",
// "TF_TOKEN_xn--caf-dma_fr", or "TF_TOKEN_xn--caf-dma.fr"
func hostCredentialsFromEnv(host svchost.Hostname) svcauth.HostCredentials {
	token, ok := collectCredentialsFromEnv()[host]
	if !ok {
		return nil
	}
	return svcauth.HostCredentialsToken(token)
}

// CredentialsSource is an implementation of svcauth.CredentialsSource
// that can read and write the CLI configuration, and possibly also delegate
// to a credentials helper when configured.
type CredentialsSource struct {
	// configured describes the credentials explicitly configured in the CLI
	// config via "credentials" blocks. This map will also change to reflect
	// any writes to the special credentials.tfrc.json file.
	configured map[svchost.Hostname]cty.Value

	// unwritable describes any credentials explicitly configured in the
	// CLI config in any file other than credentials.tfrc.json. We cannot update
	// these automatically because only credentials.tfrc.json is subject to
	// editing by this credentials source.
	unwritable map[svchost.Hostname]cty.Value

	// credentialsFilePath is the full path to the credentials.tfrc.json file
	// that we'll update if any changes to credentials are requested and if
	// a credentials helper isn't available to use instead.
	//
	// (This is a field here rather than just calling credentialsConfigFile
	// directly just so that we can use temporary file location instead during
	// testing.)
	credentialsFilePath string

	// helper is the credentials source representing the configured credentials
	// helper, if any. When this is non-nil, it will be consulted for any
	// hostnames not explicitly represented in "configured". Any writes to
	// the credentials store will also be sent to a configured helper instead
	// of the credentials.tfrc.json file.
	helper svcauth.CredentialsSource

	// helperType is the name of the type of credentials helper that is
	// referenced in "helper", or the empty string if "helper" is nil.
	helperType string
}

// Assertion that credentialsSource implements CredentialsSource
var _ svcauth.CredentialsSource = (*CredentialsSource)(nil)

func (s *CredentialsSource) ForHost(host svchost.Hostname) (svcauth.HostCredentials, error) {
	// The first order of precedence for credentials is a host-specific environment variable
	if envCreds := hostCredentialsFromEnv(host); envCreds != nil {
		return envCreds, nil
	}

	// Then, any credentials block present in the CLI config
	v, ok := s.configured[host]
	if ok {
		return svcauth.HostCredentialsFromObject(v), nil
	}

	// And finally, the credentials helper
	if s.helper != nil {
		return s.helper.ForHost(host)
	}

	return nil, nil
}

func (s *CredentialsSource) StoreForHost(host svchost.Hostname, credentials svcauth.HostCredentialsWritable) error {
	return s.updateHostCredentials(host, credentials)
}

func (s *CredentialsSource) ForgetForHost(host svchost.Hostname) error {
	return s.updateHostCredentials(host, nil)
}

// HostCredentialsLocation returns a value indicating what type of storage is
// currently used for the credentials for the given hostname.
//
// The current location of credentials determines whether updates are possible
// at all and, if they are, where any updates will be written.
func (s *CredentialsSource) HostCredentialsLocation(host svchost.Hostname) CredentialsLocation {
	if _, unwritable := s.unwritable[host]; unwritable {
		return CredentialsInOtherFile
	}
	if _, exists := s.configured[host]; exists {
		return CredentialsInPrimaryFile
	}
	if s.helper != nil {
		return CredentialsViaHelper
	}
	return CredentialsNotAvailable
}

// CredentialsFilePath returns the full path to the local credentials
// configuration file, so that a caller can mention this path in order to
// be transparent about where credentials will be stored.
//
// This file will be used for writes only if HostCredentialsLocation for the
// relevant host returns CredentialsInPrimaryFile or CredentialsNotAvailable.
//
// The credentials file path is found relative to the current user's home
// directory, so this function will return an error in the unlikely event that
// we cannot determine a suitable home directory to resolve relative to.
func (s *CredentialsSource) CredentialsFilePath() (string, error) {
	return s.credentialsFilePath, nil
}

// CredentialsHelperType returns the name of the configured credentials helper
// type, or an empty string if no credentials helper is configured.
func (s *CredentialsSource) CredentialsHelperType() string {
	return s.helperType
}

func (s *CredentialsSource) updateHostCredentials(host svchost.Hostname, new svcauth.HostCredentialsWritable) error {
	switch loc := s.HostCredentialsLocation(host); loc {
	case CredentialsInOtherFile:
		return ErrUnwritableHostCredentials(host)
	case CredentialsInPrimaryFile, CredentialsNotAvailable:
		// If the host already has credentials stored locally then we'll update
		// them locally too, even if there's a credentials helper configured,
		// because the user might be intentionally retaining this particular
		// host locally for some reason, e.g. if the credentials helper is
		// talking to some shared remote service like HashiCorp Vault.
		return s.updateLocalHostCredentials(host, new)
	case CredentialsViaHelper:
		// Delegate entirely to the helper, then.
		if new == nil {
			return s.helper.ForgetForHost(host)
		}
		return s.helper.StoreForHost(host, new)
	default:
		// Should never happen because the above cases are exhaustive
		return fmt.Errorf("invalid credentials location %#v", loc)
	}
}

func (s *CredentialsSource) updateLocalHostCredentials(host svchost.Hostname, new svcauth.HostCredentialsWritable) error {
	// This function updates the local credentials file in particular,
	// regardless of whether a credentials helper is active. It should be
	// called only indirectly via updateHostCredentials.

	filename, err := s.CredentialsFilePath()
	if err != nil {
		return fmt.Errorf("unable to determine credentials file path: %s", err)
	}

	oldSrc, err := ioutil.ReadFile(filename)
	if err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("cannot read %s: %s", filename, err)
	}

	var raw map[string]interface{}

	if len(oldSrc) > 0 {
		// When decoding we use a custom decoder so we can decode any numbers as
		// json.Number and thus avoid losing any accuracy in our round-trip.
		dec := json.NewDecoder(bytes.NewReader(oldSrc))
		dec.UseNumber()
		err = dec.Decode(&raw)
		if err != nil {
			return fmt.Errorf("cannot read %s: %s", filename, err)
		}
	} else {
		raw = make(map[string]interface{})
	}

	rawCredsI, ok := raw["credentials"]
	if !ok {
		rawCredsI = make(map[string]interface{})
		raw["credentials"] = rawCredsI
	}
	rawCredsMap, ok := rawCredsI.(map[string]interface{})
	if !ok {
		return fmt.Errorf("credentials file %s has invalid value for \"credentials\" property: must be a JSON object", filename)
	}

	// We use display-oriented hostnames in our file to mimick how a human user
	// would write it, so we need to search for and remove any key that
	// normalizes to our target hostname so we won't generate something invalid
	// when the existing entry is slightly different.
	for givenHost := range rawCredsMap {
		canonHost, err := svchost.ForComparison(givenHost)
		if err == nil && canonHost == host {
			delete(rawCredsMap, givenHost)
		}
	}

	// If we have a new object to store we'll write it in now. If the previous
	// object had the hostname written in a different way then this will
	// appear to change it into our canonical display form, with all the
	// letters in lowercase and other transforms from the Internationalized
	// Domain Names specification.
	if new != nil {
		toStore := new.ToStore()
		rawCredsMap[host.ForDisplay()] = ctyjson.SimpleJSONValue{
			Value: toStore,
		}
	}

	newSrc, err := json.MarshalIndent(raw, "", "  ")
	if err != nil {
		return fmt.Errorf("cannot serialize updated credentials file: %s", err)
	}

	// Now we'll write our new content over the top of the existing file.
	// Because we updated the data structure surgically here we should not
	// have disturbed the meaning of any other content in the file, but it
	// might have a different JSON layout than before.
	// We'll create a new file with a different name first and then rename
	// it over the old file in order to make the change as atomically as
	// the underlying OS/filesystem will allow.
	{
		dir, file := filepath.Split(filename)
		f, err := ioutil.TempFile(dir, file)
		if err != nil {
			return fmt.Errorf("cannot create temporary file to update credentials: %s", err)
		}
		tmpName := f.Name()
		moved := false
		defer func(f *os.File, name string) {
			// Remove the temporary file if it hasn't been moved yet. We're
			// ignoring errors here because there's nothing we can do about
			// them anyway.
			if !moved {
				os.Remove(name)
			}
		}(f, tmpName)

		// Write the credentials to the temporary file, then immediately close
		// it, whether or not the write succeeds.
		_, err = f.Write(newSrc)
		f.Close()
		if err != nil {
			return fmt.Errorf("cannot write to temporary file %s: %s", tmpName, err)
		}

		// Temporary file now replaces the original file, as atomically as
		// possible. (At the very least, we should not end up with a file
		// containing only a partial JSON object.)
		err = replacefile.AtomicRename(tmpName, filename)
		if err != nil {
			return fmt.Errorf("failed to replace %s with temporary file %s: %s", filename, tmpName, err)
		}

		// Credentials file should be readable only by its owner. (This may
		// not be effective on all platforms, but should at least work on
		// Unix-like targets and should be harmless elsewhere.)
		if err := os.Chmod(filename, 0600); err != nil {
			return fmt.Errorf("cannot set mode for credentials file %s: %s", filename, err)
		}

		moved = true
	}

	if new != nil {
		s.configured[host] = new.ToStore()
	} else {
		delete(s.configured, host)
	}

	return nil
}

// readHostsInCredentialsFile discovers which hosts have credentials configured
// in the credentials file specifically, as opposed to in any other CLI
// config file.
//
// If the credentials file isn't present or is unreadable for any reason then
// this returns an empty set, reflecting that effectively no credentials are
// stored there.
func readHostsInCredentialsFile(filename string) map[svchost.Hostname]struct{} {
	src, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil
	}

	var raw map[string]interface{}
	err = json.Unmarshal(src, &raw)
	if err != nil {
		return nil
	}

	rawCredsI, ok := raw["credentials"]
	if !ok {
		return nil
	}
	rawCredsMap, ok := rawCredsI.(map[string]interface{})
	if !ok {
		return nil
	}

	ret := make(map[svchost.Hostname]struct{})
	for givenHost := range rawCredsMap {
		host, err := svchost.ForComparison(givenHost)
		if err != nil {
			// We expect the config was already validated by the time we get
			// here, so we'll just ignore invalid hostnames.
			continue
		}
		ret[host] = struct{}{}
	}
	return ret
}

// ErrUnwritableHostCredentials is an error type that is returned when a caller
// tries to write credentials for a host that has existing credentials configured
// in a file that we cannot automatically update.
type ErrUnwritableHostCredentials svchost.Hostname

func (err ErrUnwritableHostCredentials) Error() string {
	return fmt.Sprintf("cannot change credentials for %s: existing manually-configured credentials in a CLI config file", svchost.Hostname(err).ForDisplay())
}

// Hostname returns the host that could not be written.
func (err ErrUnwritableHostCredentials) Hostname() svchost.Hostname {
	return svchost.Hostname(err)
}

// CredentialsLocation describes a type of storage used for the credentials
// for a particular hostname.
type CredentialsLocation rune

const (
	// CredentialsNotAvailable means that we know that there are no credential
	// available for the host.
	//
	// Note that CredentialsViaHelper might also lead to no credentials being
	// available, depending on how the helper answers when we request credentials
	// from it.
	CredentialsNotAvailable CredentialsLocation = 0

	// CredentialsInPrimaryFile means that there is already a credentials object
	// for the host in the credentials.tfrc.json file.
	CredentialsInPrimaryFile CredentialsLocation = 'P'

	// CredentialsInOtherFile means that there is already a credentials object
	// for the host in a CLI config file other than credentials.tfrc.json.
	CredentialsInOtherFile CredentialsLocation = 'O'

	// CredentialsViaHelper indicates that no statically-configured credentials
	// are available for the host but a helper program is available that may
	// or may not have credentials for the host.
	CredentialsViaHelper CredentialsLocation = 'H'
)
