// Copyright 2016 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package environ is an environment variable manipulation library.
//
// It couples the system's environment, represented as a []string of KEY[=VALUE]
// strings, into a key/value map and back.
package environ

import (
	"context"
	"fmt"
	"os"
	"runtime"
	"sort"
	"strings"
)

// Env contains system environment variables. It preserves each environment
// variable verbatim (even if invalid).
//
// Internally env is represented by a map of environment key to its "KEY=VALUE"
// value. Note that the value here is the full "KEY=VALUE", not just the VALUE
// part. This allows us to reconstitute the original environment string slice
// without reallocating all of its composite strings.
type Env map[string]string

var ctxKey = "holds an Env"

// FromCtx returns a copy of the current Env in `ctx`.
//
// This is guaranteed to return a non-nil Env (i.e. it's always safe for
// assignment/manipulation)
//
// If no Env has been set with With, this returns `System()`.
func FromCtx(ctx context.Context) Env {
	if cur, ok := ctx.Value(&ctxKey).(Env); ok {
		if cur != nil {
			return cur.Clone()
		}
		return Env{}
	}
	return System()
}

// SetInCtx installs a copy of the Env into the context, which can be retrieved
// with `FromCtx`.
func (e Env) SetInCtx(ctx context.Context) context.Context {
	return context.WithValue(ctx, &ctxKey, e.Clone())
}

// System returns an Env instance instantiated with the current os.Environ
// values.
//
// The environment is automatically configured with the local system's case
// insensitivity.
func System() Env {
	return New(os.Environ())
}

// New instantiates a new Env instance from the supplied set of environment
// KEY=VALUE strings using LoadSlice.
//
// The environment is automatically configured with the local system's case
// insensitivity.
func New(s []string) Env {
	e := make(Env, len(s))
	for _, entry := range s {
		e.SetEntry(entry)
	}
	return e
}

// String returns debug representation of Env.
func (e Env) String() string { return fmt.Sprintf("%v", e.Sorted()) }

// Load adds environment variables defined in a key/value map to an existing
// environment.
func (e Env) Load(m map[string]string) {
	for k, v := range m {
		e.Set(k, v)
	}
}

// Set sets the supplied environment key and value.
func (e Env) Set(k, v string) { e.SetEntry(Join(k, v)) }

// SetEntry sets the supplied environment to a "KEY[=VALUE]" entry.
func (e Env) SetEntry(entry string) {
	if e == nil {
		panic("cannot modify nil Env")
	}

	// "entry" must be a well-formed "key=value" entry. If it doesn't have an "=",
	// we will forcibly add one to make it well-formed.
	if strings.IndexRune(entry, '=') < 0 {
		entry += "="
	}
	k, _ := Split(entry)
	if len(k) > 0 {
		e[normalizeKeyCase(k)] = entry
	}
}

// Remove removes a value from the environment, returning true if the value was
// present. If the value was missing, Remove returns false.
//
// Remove is different from Set(k, "") in that Set persists the key with an
// empty value, while Remove removes it entirely.
func (e Env) Remove(k string) bool {
	k = normalizeKeyCase(k)
	if _, ok := e[k]; ok {
		delete(e, k)
		return true
	}
	return false
}

// RemoveMatch iterates over all keys and values in the environment, invoking
// the callback function, fn, for each key/value pair. If fn returns true, the
// key is removed from the environment.
func (e Env) RemoveMatch(fn func(k, v string) bool) {
	e.iterate(func(realKey, k, v string) error {
		if fn(k, v) {
			delete(e, realKey)
		}
		return nil
	})
}

// Update adds all key/value from other to the current environment. If there is
// a duplicate key, the value from other will overwrite the value from e.
//
// Values from other will be sorted and added in alphabetic order. This means
// that if e is case insensitive and there are multiple keys in other that
// converge on the same case insensitive key, the one that is alphabetically
// highest will be added.
func (e Env) Update(other Env) {
	for _, entry := range other.Sorted() {
		e.SetEntry(entry)
	}
}

// Get returns the environment value for the supplied key.
//
// If the value is defined, ok will be true and v will be set to its value (note
// that this can be empty if the environment has an empty value). If the value
// is not defined, ok will be false.
func (e Env) Get(k string) (v string, ok bool) {
	// NOTE: "v" is initially the combined "key=value" entry, and will need to be
	// split.
	if v, ok = e[normalizeKeyCase(k)]; ok {
		_, v = splitEntryGivenKey(k, v)
	}
	return
}

// GetEmpty is the same as Get, except that instead of returning a separate
// boolean indicating the presence of a key, it will return an empty string if
// the key is missing.
func (e Env) GetEmpty(k string) string {
	v, _ := e.Get(k)
	return v
}

// Sorted returns the contents of the environment, sorted by key.
func (e Env) Sorted() []string {
	var r []string
	if len(e) > 0 {
		r = make([]string, 0, len(e))
		for _, v := range e {
			r = append(r, v)
		}
		sort.Strings(r)
	}
	return r
}

// Map returns a map of the key/value values in the environment.
//
// This is a clone of the contents of e; manipulating this map will not change
// the values in e.
//
// If env is either nil or empty, returns nil.
func (e Env) Map() map[string]string {
	if len(e) == 0 {
		return nil
	}
	m := make(map[string]string, len(e))
	for k, entry := range e {
		ek, ev := splitEntryGivenKey(k, entry)
		m[ek] = ev
	}
	return m
}

// Len returns the number of environment variables defined in e.
func (e Env) Len() int { return len(e) }

// Clone creates a new Env instance that is identical to, but independent from,
// e.
//
// If e is nil, returns nil. Otherwise returns a new (perhaps empty) Env.
func (e Env) Clone() Env {
	if e == nil {
		return nil
	}
	clone := make(Env, len(e))
	for k, v := range e {
		clone[k] = v
	}
	return clone
}

// Internal iteration function. Invokes cb for every entry in the environment.
// If the callback returns error, iteration stops and returns that error.
//
// It is safe to mutate the environment map during iteration.
//
// realKey is the real, normalized map key. envKey and envValue are the split
// map value.
func (e Env) iterate(cb func(realKey, envKey, envValue string) error) error {
	for k, v := range e {
		envKey, envValue := Split(v)
		if err := cb(k, envKey, envValue); err != nil {
			return err
		}
	}
	return nil
}

// Iter iterates through all of the key/value pairs in Env and invokes the
// supplied callback, cb, for each element.
//
// If the callback returns error, iteration will stop immediately.
func (e Env) Iter(cb func(k, v string) error) error {
	return e.iterate(func(_, k, v string) error { return cb(k, v) })
}

// Split splits the supplied environment variable value into a key/value pair.
//
// If v is of the form:
//  - KEY, returns (KEY, "")
//  - KEY=, returns (KEY, "")
//  - KEY=VALUE, returns (KEY, VALUE)
func Split(v string) (key, value string) {
	parts := strings.SplitN(v, "=", 2)
	switch len(parts) {
	case 2:
		value = parts[1]
		fallthrough

	case 1:
		key = parts[0]
	}
	return
}

// Join creates an environment variable definition for the supplied key/value.
func Join(k, v string) string {
	if v == "" {
		return k + "="
	}
	return k + "=" + v
}

// splitEntryGivenKey extracts the key and value components of the "env" map's
// combined "key=value" field, given the "key" component.
//
// This will work as long as the length of the supplied key equals the length of
// entry's key prefix, regardless of the key's contents which means that
// normalized keys can be used.
//
// It assumes that the environment variable is well-formed, one of:
// - KEY (returns "")
// - KEY= (returns "")
// - KEY=VALUE (returns "VALUE")
//
// If this is not the case, the result is undefined. However, this is an
// internal function and should never encounter a situation where the entry is
// not well-formed and prefixed by the supplied key.
func splitEntryGivenKey(key, entry string) (k, v string) {
	prefixSize := len(key) + len("=")
	switch {
	case len(entry) < prefixSize:
		return entry, ""
	case len(entry) == prefixSize:
		return entry[:len(key)], ""
	default:
		return entry[:len(key)], entry[prefixSize:]
	}
}

// normalizeKeyCase normalizes the map key by upper-casing it on Windows.
//
// Returns the key unchanged on other platforms. Mocked in tests.
var normalizeKeyCase func(string) string

func init() {
	// Note: we don't use +build flags to be able to unit test both variants on
	// a single platform just by mocking 'normalizeKeyCase' value.
	if runtime.GOOS == "windows" {
		normalizeKeyCase = strings.ToUpper
	} else {
		normalizeKeyCase = func(k string) string { return k }
	}
}
