// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

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'
)
