// Copyright 2017 Frank Schroeder. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package properties

// BUG(frank): Set() does not check for invalid unicode literals since this is currently handled by the lexer.
// BUG(frank): Write() does not allow to configure the newline character. Therefore, on Windows LF is used.

import (
	"fmt"
	"io"
	"log"
	"os"
	"regexp"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

// ErrorHandlerFunc defines the type of function which handles failures
// of the MustXXX() functions. An error handler function must exit
// the application after handling the error.
type ErrorHandlerFunc func(error)

// ErrorHandler is the function which handles failures of the MustXXX()
// functions. The default is LogFatalHandler.
var ErrorHandler ErrorHandlerFunc = LogFatalHandler

// LogHandlerFunc defines the function prototype for logging errors.
type LogHandlerFunc func(fmt string, args ...interface{})

// LogPrintf defines a log handler which uses log.Printf.
var LogPrintf LogHandlerFunc = log.Printf

// LogFatalHandler handles the error by logging a fatal error and exiting.
func LogFatalHandler(err error) {
	log.Fatal(err)
}

// PanicHandler handles the error by panicking.
func PanicHandler(err error) {
	panic(err)
}

// -----------------------------------------------------------------------------

// A Properties contains the key/value pairs from the properties input.
// All values are stored in unexpanded form and are expanded at runtime
type Properties struct {
	// Pre-/Postfix for property expansion.
	Prefix  string
	Postfix string

	// DisableExpansion controls the expansion of properties on Get()
	// and the check for circular references on Set(). When set to
	// true Properties behaves like a simple key/value store and does
	// not check for circular references on Get() or on Set().
	DisableExpansion bool

	// Stores the key/value pairs
	m map[string]string

	// Stores the comments per key.
	c map[string][]string

	// Stores the keys in order of appearance.
	k []string
}

// NewProperties creates a new Properties struct with the default
// configuration for "${key}" expressions.
func NewProperties() *Properties {
	return &Properties{
		Prefix:  "${",
		Postfix: "}",
		m:       map[string]string{},
		c:       map[string][]string{},
		k:       []string{},
	}
}

// Get returns the expanded value for the given key if exists.
// Otherwise, ok is false.
func (p *Properties) Get(key string) (value string, ok bool) {
	v, ok := p.m[key]
	if p.DisableExpansion {
		return v, ok
	}
	if !ok {
		return "", false
	}

	expanded, err := p.expand(v)

	// we guarantee that the expanded value is free of
	// circular references and malformed expressions
	// so we panic if we still get an error here.
	if err != nil {
		ErrorHandler(fmt.Errorf("%s in %q", err, key+" = "+v))
	}

	return expanded, true
}

// MustGet returns the expanded value for the given key if exists.
// Otherwise, it panics.
func (p *Properties) MustGet(key string) string {
	if v, ok := p.Get(key); ok {
		return v
	}
	ErrorHandler(invalidKeyError(key))
	panic("ErrorHandler should exit")
}

// ----------------------------------------------------------------------------

// ClearComments removes the comments for all keys.
func (p *Properties) ClearComments() {
	p.c = map[string][]string{}
}

// ----------------------------------------------------------------------------

// GetComment returns the last comment before the given key or an empty string.
func (p *Properties) GetComment(key string) string {
	comments, ok := p.c[key]
	if !ok || len(comments) == 0 {
		return ""
	}
	return comments[len(comments)-1]
}

// ----------------------------------------------------------------------------

// GetComments returns all comments that appeared before the given key or nil.
func (p *Properties) GetComments(key string) []string {
	if comments, ok := p.c[key]; ok {
		return comments
	}
	return nil
}

// ----------------------------------------------------------------------------

// SetComment sets the comment for the key.
func (p *Properties) SetComment(key, comment string) {
	p.c[key] = []string{comment}
}

// ----------------------------------------------------------------------------

// SetComments sets the comments for the key. If the comments are nil then
// all comments for this key are deleted.
func (p *Properties) SetComments(key string, comments []string) {
	if comments == nil {
		delete(p.c, key)
		return
	}
	p.c[key] = comments
}

// ----------------------------------------------------------------------------

// GetBool checks if the expanded value is one of '1', 'yes',
// 'true' or 'on' if the key exists. The comparison is case-insensitive.
// If the key does not exist the default value is returned.
func (p *Properties) GetBool(key string, def bool) bool {
	v, err := p.getBool(key)
	if err != nil {
		return def
	}
	return v
}

// MustGetBool checks if the expanded value is one of '1', 'yes',
// 'true' or 'on' if the key exists. The comparison is case-insensitive.
// If the key does not exist the function panics.
func (p *Properties) MustGetBool(key string) bool {
	v, err := p.getBool(key)
	if err != nil {
		ErrorHandler(err)
	}
	return v
}

func (p *Properties) getBool(key string) (value bool, err error) {
	if v, ok := p.Get(key); ok {
		return boolVal(v), nil
	}
	return false, invalidKeyError(key)
}

func boolVal(v string) bool {
	v = strings.ToLower(v)
	return v == "1" || v == "true" || v == "yes" || v == "on"
}

// ----------------------------------------------------------------------------

// GetDuration parses the expanded value as an time.Duration (in ns) if the
// key exists. If key does not exist or the value cannot be parsed the default
// value is returned. In almost all cases you want to use GetParsedDuration().
func (p *Properties) GetDuration(key string, def time.Duration) time.Duration {
	v, err := p.getInt64(key)
	if err != nil {
		return def
	}
	return time.Duration(v)
}

// MustGetDuration parses the expanded value as an time.Duration (in ns) if
// the key exists. If key does not exist or the value cannot be parsed the
// function panics. In almost all cases you want to use MustGetParsedDuration().
func (p *Properties) MustGetDuration(key string) time.Duration {
	v, err := p.getInt64(key)
	if err != nil {
		ErrorHandler(err)
	}
	return time.Duration(v)
}

// ----------------------------------------------------------------------------

// GetParsedDuration parses the expanded value with time.ParseDuration() if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned.
func (p *Properties) GetParsedDuration(key string, def time.Duration) time.Duration {
	s, ok := p.Get(key)
	if !ok {
		return def
	}
	v, err := time.ParseDuration(s)
	if err != nil {
		return def
	}
	return v
}

// MustGetParsedDuration parses the expanded value with time.ParseDuration() if the key exists.
// If key does not exist or the value cannot be parsed the function panics.
func (p *Properties) MustGetParsedDuration(key string) time.Duration {
	s, ok := p.Get(key)
	if !ok {
		ErrorHandler(invalidKeyError(key))
	}
	v, err := time.ParseDuration(s)
	if err != nil {
		ErrorHandler(err)
	}
	return v
}

// ----------------------------------------------------------------------------

// GetFloat64 parses the expanded value as a float64 if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned.
func (p *Properties) GetFloat64(key string, def float64) float64 {
	v, err := p.getFloat64(key)
	if err != nil {
		return def
	}
	return v
}

// MustGetFloat64 parses the expanded value as a float64 if the key exists.
// If key does not exist or the value cannot be parsed the function panics.
func (p *Properties) MustGetFloat64(key string) float64 {
	v, err := p.getFloat64(key)
	if err != nil {
		ErrorHandler(err)
	}
	return v
}

func (p *Properties) getFloat64(key string) (value float64, err error) {
	if v, ok := p.Get(key); ok {
		value, err = strconv.ParseFloat(v, 64)
		if err != nil {
			return 0, err
		}
		return value, nil
	}
	return 0, invalidKeyError(key)
}

// ----------------------------------------------------------------------------

// GetInt parses the expanded value as an int if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned. If the value does not fit into an int the
// function panics with an out of range error.
func (p *Properties) GetInt(key string, def int) int {
	v, err := p.getInt64(key)
	if err != nil {
		return def
	}
	return intRangeCheck(key, v)
}

// MustGetInt parses the expanded value as an int if the key exists.
// If key does not exist or the value cannot be parsed the function panics.
// If the value does not fit into an int the function panics with
// an out of range error.
func (p *Properties) MustGetInt(key string) int {
	v, err := p.getInt64(key)
	if err != nil {
		ErrorHandler(err)
	}
	return intRangeCheck(key, v)
}

// ----------------------------------------------------------------------------

// GetInt64 parses the expanded value as an int64 if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned.
func (p *Properties) GetInt64(key string, def int64) int64 {
	v, err := p.getInt64(key)
	if err != nil {
		return def
	}
	return v
}

// MustGetInt64 parses the expanded value as an int if the key exists.
// If key does not exist or the value cannot be parsed the function panics.
func (p *Properties) MustGetInt64(key string) int64 {
	v, err := p.getInt64(key)
	if err != nil {
		ErrorHandler(err)
	}
	return v
}

func (p *Properties) getInt64(key string) (value int64, err error) {
	if v, ok := p.Get(key); ok {
		value, err = strconv.ParseInt(v, 10, 64)
		if err != nil {
			return 0, err
		}
		return value, nil
	}
	return 0, invalidKeyError(key)
}

// ----------------------------------------------------------------------------

// GetUint parses the expanded value as an uint if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned. If the value does not fit into an int the
// function panics with an out of range error.
func (p *Properties) GetUint(key string, def uint) uint {
	v, err := p.getUint64(key)
	if err != nil {
		return def
	}
	return uintRangeCheck(key, v)
}

// MustGetUint parses the expanded value as an int if the key exists.
// If key does not exist or the value cannot be parsed the function panics.
// If the value does not fit into an int the function panics with
// an out of range error.
func (p *Properties) MustGetUint(key string) uint {
	v, err := p.getUint64(key)
	if err != nil {
		ErrorHandler(err)
	}
	return uintRangeCheck(key, v)
}

// ----------------------------------------------------------------------------

// GetUint64 parses the expanded value as an uint64 if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned.
func (p *Properties) GetUint64(key string, def uint64) uint64 {
	v, err := p.getUint64(key)
	if err != nil {
		return def
	}
	return v
}

// MustGetUint64 parses the expanded value as an int if the key exists.
// If key does not exist or the value cannot be parsed the function panics.
func (p *Properties) MustGetUint64(key string) uint64 {
	v, err := p.getUint64(key)
	if err != nil {
		ErrorHandler(err)
	}
	return v
}

func (p *Properties) getUint64(key string) (value uint64, err error) {
	if v, ok := p.Get(key); ok {
		value, err = strconv.ParseUint(v, 10, 64)
		if err != nil {
			return 0, err
		}
		return value, nil
	}
	return 0, invalidKeyError(key)
}

// ----------------------------------------------------------------------------

// GetString returns the expanded value for the given key if exists or
// the default value otherwise.
func (p *Properties) GetString(key, def string) string {
	if v, ok := p.Get(key); ok {
		return v
	}
	return def
}

// MustGetString returns the expanded value for the given key if exists or
// panics otherwise.
func (p *Properties) MustGetString(key string) string {
	if v, ok := p.Get(key); ok {
		return v
	}
	ErrorHandler(invalidKeyError(key))
	panic("ErrorHandler should exit")
}

// ----------------------------------------------------------------------------

// Filter returns a new properties object which contains all properties
// for which the key matches the pattern.
func (p *Properties) Filter(pattern string) (*Properties, error) {
	re, err := regexp.Compile(pattern)
	if err != nil {
		return nil, err
	}

	return p.FilterRegexp(re), nil
}

// FilterRegexp returns a new properties object which contains all properties
// for which the key matches the regular expression.
func (p *Properties) FilterRegexp(re *regexp.Regexp) *Properties {
	pp := NewProperties()
	for _, k := range p.k {
		if re.MatchString(k) {
			// TODO(fs): we are ignoring the error which flags a circular reference.
			// TODO(fs): since we are just copying a subset of keys this cannot happen (fingers crossed)
			pp.Set(k, p.m[k])
		}
	}
	return pp
}

// FilterPrefix returns a new properties object with a subset of all keys
// with the given prefix.
func (p *Properties) FilterPrefix(prefix string) *Properties {
	pp := NewProperties()
	for _, k := range p.k {
		if strings.HasPrefix(k, prefix) {
			// TODO(fs): we are ignoring the error which flags a circular reference.
			// TODO(fs): since we are just copying a subset of keys this cannot happen (fingers crossed)
			pp.Set(k, p.m[k])
		}
	}
	return pp
}

// FilterStripPrefix returns a new properties object with a subset of all keys
// with the given prefix and the prefix removed from the keys.
func (p *Properties) FilterStripPrefix(prefix string) *Properties {
	pp := NewProperties()
	n := len(prefix)
	for _, k := range p.k {
		if len(k) > len(prefix) && strings.HasPrefix(k, prefix) {
			// TODO(fs): we are ignoring the error which flags a circular reference.
			// TODO(fs): since we are modifying keys I am not entirely sure whether we can create a circular reference
			// TODO(fs): this function should probably return an error but the signature is fixed
			pp.Set(k[n:], p.m[k])
		}
	}
	return pp
}

// Len returns the number of keys.
func (p *Properties) Len() int {
	return len(p.m)
}

// Keys returns all keys in the same order as in the input.
func (p *Properties) Keys() []string {
	keys := make([]string, len(p.k))
	copy(keys, p.k)
	return keys
}

// Set sets the property key to the corresponding value.
// If a value for key existed before then ok is true and prev
// contains the previous value. If the value contains a
// circular reference or a malformed expression then
// an error is returned.
// An empty key is silently ignored.
func (p *Properties) Set(key, value string) (prev string, ok bool, err error) {
	if key == "" {
		return "", false, nil
	}

	// if expansion is disabled we allow circular references
	if p.DisableExpansion {
		prev, ok = p.Get(key)
		p.m[key] = value
		return prev, ok, nil
	}

	// to check for a circular reference we temporarily need
	// to set the new value. If there is an error then revert
	// to the previous state. Only if all tests are successful
	// then we add the key to the p.k list.
	prev, ok = p.Get(key)
	p.m[key] = value

	// now check for a circular reference
	_, err = p.expand(value)
	if err != nil {

		// revert to the previous state
		if ok {
			p.m[key] = prev
		} else {
			delete(p.m, key)
		}

		return "", false, err
	}

	if !ok {
		p.k = append(p.k, key)
	}

	return prev, ok, nil
}

// SetValue sets property key to the default string value
// as defined by fmt.Sprintf("%v").
func (p *Properties) SetValue(key string, value interface{}) error {
	_, _, err := p.Set(key, fmt.Sprintf("%v", value))
	return err
}

// MustSet sets the property key to the corresponding value.
// If a value for key existed before then ok is true and prev
// contains the previous value. An empty key is silently ignored.
func (p *Properties) MustSet(key, value string) (prev string, ok bool) {
	prev, ok, err := p.Set(key, value)
	if err != nil {
		ErrorHandler(err)
	}
	return prev, ok
}

// String returns a string of all expanded 'key = value' pairs.
func (p *Properties) String() string {
	var s string
	for _, key := range p.k {
		value, _ := p.Get(key)
		s = fmt.Sprintf("%s%s = %s\n", s, key, value)
	}
	return s
}

// Write writes all unexpanded 'key = value' pairs to the given writer.
// Write returns the number of bytes written and any write error encountered.
func (p *Properties) Write(w io.Writer, enc Encoding) (n int, err error) {
	return p.WriteComment(w, "", enc)
}

// WriteComment writes all unexpanced 'key = value' pairs to the given writer.
// If prefix is not empty then comments are written with a blank line and the
// given prefix. The prefix should be either "# " or "! " to be compatible with
// the properties file format. Otherwise, the properties parser will not be
// able to read the file back in. It returns the number of bytes written and
// any write error encountered.
func (p *Properties) WriteComment(w io.Writer, prefix string, enc Encoding) (n int, err error) {
	var x int

	for _, key := range p.k {
		value := p.m[key]

		if prefix != "" {
			if comments, ok := p.c[key]; ok {
				// don't print comments if they are all empty
				allEmpty := true
				for _, c := range comments {
					if c != "" {
						allEmpty = false
						break
					}
				}

				if !allEmpty {
					// add a blank line between entries but not at the top
					if len(comments) > 0 && n > 0 {
						x, err = fmt.Fprintln(w)
						if err != nil {
							return
						}
						n += x
					}

					for _, c := range comments {
						x, err = fmt.Fprintf(w, "%s%s\n", prefix, encode(c, "", enc))
						if err != nil {
							return
						}
						n += x
					}
				}
			}
		}

		x, err = fmt.Fprintf(w, "%s = %s\n", encode(key, " :", enc), encode(value, "", enc))
		if err != nil {
			return
		}
		n += x
	}
	return
}

// Map returns a copy of the properties as a map.
func (p *Properties) Map() map[string]string {
	m := make(map[string]string)
	for k, v := range p.m {
		m[k] = v
	}
	return m
}

// FilterFunc returns a copy of the properties which includes the values which passed all filters.
func (p *Properties) FilterFunc(filters ...func(k, v string) bool) *Properties {
	pp := NewProperties()
outer:
	for k, v := range p.m {
		for _, f := range filters {
			if !f(k, v) {
				continue outer
			}
			pp.Set(k, v)
		}
	}
	return pp
}

// ----------------------------------------------------------------------------

// Delete removes the key and its comments.
func (p *Properties) Delete(key string) {
	delete(p.m, key)
	delete(p.c, key)
	newKeys := []string{}
	for _, k := range p.k {
		if k != key {
			newKeys = append(newKeys, k)
		}
	}
	p.k = newKeys
}

// Merge merges properties, comments and keys from other *Properties into p
func (p *Properties) Merge(other *Properties) {
	for k, v := range other.m {
		p.m[k] = v
	}
	for k, v := range other.c {
		p.c[k] = v
	}

outer:
	for _, otherKey := range other.k {
		for _, key := range p.k {
			if otherKey == key {
				continue outer
			}
		}
		p.k = append(p.k, otherKey)
	}
}

// ----------------------------------------------------------------------------

// check expands all values and returns an error if a circular reference or
// a malformed expression was found.
func (p *Properties) check() error {
	for _, value := range p.m {
		if _, err := p.expand(value); err != nil {
			return err
		}
	}
	return nil
}

func (p *Properties) expand(input string) (string, error) {
	// no pre/postfix -> nothing to expand
	if p.Prefix == "" && p.Postfix == "" {
		return input, nil
	}

	return expand(input, make(map[string]bool), p.Prefix, p.Postfix, p.m)
}

// expand recursively expands expressions of '(prefix)key(postfix)' to their corresponding values.
// The function keeps track of the keys that were already expanded and stops if it
// detects a circular reference or a malformed expression of the form '(prefix)key'.
func expand(s string, keys map[string]bool, prefix, postfix string, values map[string]string) (string, error) {
	start := strings.Index(s, prefix)
	if start == -1 {
		return s, nil
	}

	keyStart := start + len(prefix)
	keyLen := strings.Index(s[keyStart:], postfix)
	if keyLen == -1 {
		return "", fmt.Errorf("malformed expression")
	}

	end := keyStart + keyLen + len(postfix) - 1
	key := s[keyStart : keyStart+keyLen]

	// fmt.Printf("s:%q pp:%q start:%d end:%d keyStart:%d keyLen:%d key:%q\n", s, prefix + "..." + postfix, start, end, keyStart, keyLen, key)

	if _, ok := keys[key]; ok {
		return "", fmt.Errorf("circular reference")
	}

	val, ok := values[key]
	if !ok {
		val = os.Getenv(key)
	}

	// remember that we've seen the key
	keys[key] = true

	return expand(s[:start]+val+s[end+1:], keys, prefix, postfix, values)
}

// encode encodes a UTF-8 string to ISO-8859-1 and escapes some characters.
func encode(s string, special string, enc Encoding) string {
	switch enc {
	case UTF8:
		return encodeUtf8(s, special)
	case ISO_8859_1:
		return encodeIso(s, special)
	default:
		panic(fmt.Sprintf("unsupported encoding %v", enc))
	}
}

func encodeUtf8(s string, special string) string {
	v := ""
	for pos := 0; pos < len(s); {
		r, w := utf8.DecodeRuneInString(s[pos:])
		pos += w
		v += escape(r, special)
	}
	return v
}

func encodeIso(s string, special string) string {
	var r rune
	var w int
	var v string
	for pos := 0; pos < len(s); {
		switch r, w = utf8.DecodeRuneInString(s[pos:]); {
		case r < 1<<8: // single byte rune -> escape special chars only
			v += escape(r, special)
		case r < 1<<16: // two byte rune -> unicode literal
			v += fmt.Sprintf("\\u%04x", r)
		default: // more than two bytes per rune -> can't encode
			v += "?"
		}
		pos += w
	}
	return v
}

func escape(r rune, special string) string {
	switch r {
	case '\f':
		return "\\f"
	case '\n':
		return "\\n"
	case '\r':
		return "\\r"
	case '\t':
		return "\\t"
	default:
		if strings.ContainsRune(special, r) {
			return "\\" + string(r)
		}
		return string(r)
	}
}

func invalidKeyError(key string) error {
	return fmt.Errorf("unknown property: %s", key)
}
