// Copyright 2013-2014 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 = LogFatalHandler

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

	// 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 !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 {
		v = strings.ToLower(v)
		return v == "1" || v == "true" || v == "yes" || v == "on", nil
	}
	return false, invalidKeyError(key)
}

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

// GetDuration parses the expanded value as an time.Duration if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned.
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 if the key exists.
// If key does not exist or the value cannot be parsed the function panics.
func (p *Properties) MustGetDuration(key string) time.Duration {
	v, err := p.getInt64(key)
	if err != nil {
		ErrorHandler(err)
	}
	return time.Duration(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, v := range p.m {
		if re.MatchString(k) {
			pp.Set(k, v)
		}
	}
	return pp
}

// FilterPrefix returns a new properties object which contains all properties
// for which the key starts with the prefix.
func (p *Properties) FilterPrefix(prefix string) *Properties {
	pp := NewProperties()
	for k, v := range p.m {
		if strings.HasPrefix(k, prefix) {
			pp.Set(k, v)
		}
	}
	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))
	for i, k := range p.k {
		keys[i] = 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
	}

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

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

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

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