package hclwrite

import (
	"fmt"
	"unicode"
	"unicode/utf8"

	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/hcl/v2/hclsyntax"
	"github.com/zclconf/go-cty/cty"
)

// TokensForValue returns a sequence of tokens that represents the given
// constant value.
//
// This function only supports types that are used by HCL. In particular, it
// does not support capsule types and will panic if given one.
//
// It is not possible to express an unknown value in source code, so this
// function will panic if the given value is unknown or contains any unknown
// values. A caller can call the value's IsWhollyKnown method to verify that
// no unknown values are present before calling TokensForValue.
func TokensForValue(val cty.Value) Tokens {
	toks := appendTokensForValue(val, nil)
	format(toks) // fiddle with the SpacesBefore field to get canonical spacing
	return toks
}

// TokensForTraversal returns a sequence of tokens that represents the given
// traversal.
//
// If the traversal is absolute then the result is a self-contained, valid
// reference expression. If the traversal is relative then the returned tokens
// could be appended to some other expression tokens to traverse into the
// represented expression.
func TokensForTraversal(traversal hcl.Traversal) Tokens {
	toks := appendTokensForTraversal(traversal, nil)
	format(toks) // fiddle with the SpacesBefore field to get canonical spacing
	return toks
}

// TokensForIdentifier returns a sequence of tokens representing just the
// given identifier.
//
// In practice this function can only ever generate exactly one token, because
// an identifier is always a leaf token in the syntax tree.
//
// This is similar to calling TokensForTraversal with a single-step absolute
// traversal, but avoids the need to construct a separate traversal object
// for this simple common case. If you need to generate a multi-step traversal,
// use TokensForTraversal instead.
func TokensForIdentifier(name string) Tokens {
	return Tokens{
		newIdentToken(name),
	}
}

// TokensForTuple returns a sequence of tokens that represents a tuple
// constructor, with element expressions populated from the given list
// of tokens.
//
// TokensForTuple includes the given elements verbatim into the element
// positions in the resulting tuple expression, without any validation to
// ensure that they represent valid expressions. Use TokensForValue or
// TokensForTraversal to generate valid leaf expression values, or use
// TokensForTuple, TokensForObject, and TokensForFunctionCall to
// generate other nested compound expressions.
func TokensForTuple(elems []Tokens) Tokens {
	var toks Tokens
	toks = append(toks, &Token{
		Type:  hclsyntax.TokenOBrack,
		Bytes: []byte{'['},
	})
	for index, elem := range elems {
		if index > 0 {
			toks = append(toks, &Token{
				Type:  hclsyntax.TokenComma,
				Bytes: []byte{','},
			})
		}
		toks = append(toks, elem...)
	}

	toks = append(toks, &Token{
		Type:  hclsyntax.TokenCBrack,
		Bytes: []byte{']'},
	})

	format(toks) // fiddle with the SpacesBefore field to get canonical spacing
	return toks
}

// TokensForObject returns a sequence of tokens that represents an object
// constructor, with attribute name/value pairs populated from the given
// list of attribute token objects.
//
// TokensForObject includes the given tokens verbatim into the name and
// value positions in the resulting object expression, without any validation
// to ensure that they represent valid expressions. Use TokensForValue or
// TokensForTraversal to generate valid leaf expression values, or use
// TokensForTuple, TokensForObject, and TokensForFunctionCall to
// generate other nested compound expressions.
//
// Note that HCL requires placing a traversal expression in parentheses if
// you intend to use it as an attribute name expression, because otherwise
// the parser will interpret it as a literal attribute name. TokensForObject
// does not handle that situation automatically, so a caller must add the
// necessary `TokenOParen` and TokenCParen` manually if needed.
func TokensForObject(attrs []ObjectAttrTokens) Tokens {
	var toks Tokens
	toks = append(toks, &Token{
		Type:  hclsyntax.TokenOBrace,
		Bytes: []byte{'{'},
	})
	if len(attrs) > 0 {
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenNewline,
			Bytes: []byte{'\n'},
		})
	}
	for _, attr := range attrs {
		toks = append(toks, attr.Name...)
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenEqual,
			Bytes: []byte{'='},
		})
		toks = append(toks, attr.Value...)
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenNewline,
			Bytes: []byte{'\n'},
		})
	}
	toks = append(toks, &Token{
		Type:  hclsyntax.TokenCBrace,
		Bytes: []byte{'}'},
	})

	format(toks) // fiddle with the SpacesBefore field to get canonical spacing
	return toks
}

// TokensForFunctionCall returns a sequence of tokens that represents call
// to the function with the given name, using the argument tokens to
// populate the argument expressions.
//
// TokensForFunctionCall includes the given argument tokens verbatim into the
// positions in the resulting call expression, without any validation
// to ensure that they represent valid expressions. Use TokensForValue or
// TokensForTraversal to generate valid leaf expression values, or use
// TokensForTuple, TokensForObject, and TokensForFunctionCall to
// generate other nested compound expressions.
//
// This function doesn't include an explicit way to generate the expansion
// symbol "..." on the final argument. Currently, generating that requires
// manually appending a TokenEllipsis with the bytes "..." to the tokens for
// the final argument.
func TokensForFunctionCall(funcName string, args ...Tokens) Tokens {
	var toks Tokens
	toks = append(toks, TokensForIdentifier(funcName)...)
	toks = append(toks, &Token{
		Type:  hclsyntax.TokenOParen,
		Bytes: []byte{'('},
	})
	for index, arg := range args {
		if index > 0 {
			toks = append(toks, &Token{
				Type:  hclsyntax.TokenComma,
				Bytes: []byte{','},
			})
		}
		toks = append(toks, arg...)
	}
	toks = append(toks, &Token{
		Type:  hclsyntax.TokenCParen,
		Bytes: []byte{')'},
	})

	format(toks) // fiddle with the SpacesBefore field to get canonical spacing
	return toks
}

func appendTokensForValue(val cty.Value, toks Tokens) Tokens {
	switch {

	case !val.IsKnown():
		panic("cannot produce tokens for unknown value")

	case val.IsNull():
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenIdent,
			Bytes: []byte(`null`),
		})

	case val.Type() == cty.Bool:
		var src []byte
		if val.True() {
			src = []byte(`true`)
		} else {
			src = []byte(`false`)
		}
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenIdent,
			Bytes: src,
		})

	case val.Type() == cty.Number:
		bf := val.AsBigFloat()
		srcStr := bf.Text('f', -1)
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenNumberLit,
			Bytes: []byte(srcStr),
		})

	case val.Type() == cty.String:
		// TODO: If it's a multi-line string ending in a newline, format
		// it as a HEREDOC instead.
		src := escapeQuotedStringLit(val.AsString())
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenOQuote,
			Bytes: []byte{'"'},
		})
		if len(src) > 0 {
			toks = append(toks, &Token{
				Type:  hclsyntax.TokenQuotedLit,
				Bytes: src,
			})
		}
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenCQuote,
			Bytes: []byte{'"'},
		})

	case val.Type().IsListType() || val.Type().IsSetType() || val.Type().IsTupleType():
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenOBrack,
			Bytes: []byte{'['},
		})

		i := 0
		for it := val.ElementIterator(); it.Next(); {
			if i > 0 {
				toks = append(toks, &Token{
					Type:  hclsyntax.TokenComma,
					Bytes: []byte{','},
				})
			}
			_, eVal := it.Element()
			toks = appendTokensForValue(eVal, toks)
			i++
		}

		toks = append(toks, &Token{
			Type:  hclsyntax.TokenCBrack,
			Bytes: []byte{']'},
		})

	case val.Type().IsMapType() || val.Type().IsObjectType():
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenOBrace,
			Bytes: []byte{'{'},
		})
		if val.LengthInt() > 0 {
			toks = append(toks, &Token{
				Type:  hclsyntax.TokenNewline,
				Bytes: []byte{'\n'},
			})
		}

		i := 0
		for it := val.ElementIterator(); it.Next(); {
			eKey, eVal := it.Element()
			if hclsyntax.ValidIdentifier(eKey.AsString()) {
				toks = append(toks, &Token{
					Type:  hclsyntax.TokenIdent,
					Bytes: []byte(eKey.AsString()),
				})
			} else {
				toks = appendTokensForValue(eKey, toks)
			}
			toks = append(toks, &Token{
				Type:  hclsyntax.TokenEqual,
				Bytes: []byte{'='},
			})
			toks = appendTokensForValue(eVal, toks)
			toks = append(toks, &Token{
				Type:  hclsyntax.TokenNewline,
				Bytes: []byte{'\n'},
			})
			i++
		}

		toks = append(toks, &Token{
			Type:  hclsyntax.TokenCBrace,
			Bytes: []byte{'}'},
		})

	default:
		panic(fmt.Sprintf("cannot produce tokens for %#v", val))
	}

	return toks
}

func appendTokensForTraversal(traversal hcl.Traversal, toks Tokens) Tokens {
	for _, step := range traversal {
		toks = appendTokensForTraversalStep(step, toks)
	}
	return toks
}

func appendTokensForTraversalStep(step hcl.Traverser, toks Tokens) Tokens {
	switch ts := step.(type) {
	case hcl.TraverseRoot:
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenIdent,
			Bytes: []byte(ts.Name),
		})
	case hcl.TraverseAttr:
		toks = append(
			toks,
			&Token{
				Type:  hclsyntax.TokenDot,
				Bytes: []byte{'.'},
			},
			&Token{
				Type:  hclsyntax.TokenIdent,
				Bytes: []byte(ts.Name),
			},
		)
	case hcl.TraverseIndex:
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenOBrack,
			Bytes: []byte{'['},
		})
		toks = appendTokensForValue(ts.Key, toks)
		toks = append(toks, &Token{
			Type:  hclsyntax.TokenCBrack,
			Bytes: []byte{']'},
		})
	default:
		panic(fmt.Sprintf("unsupported traversal step type %T", step))
	}

	return toks
}

func escapeQuotedStringLit(s string) []byte {
	if len(s) == 0 {
		return nil
	}
	buf := make([]byte, 0, len(s))
	for i, r := range s {
		switch r {
		case '\n':
			buf = append(buf, '\\', 'n')
		case '\r':
			buf = append(buf, '\\', 'r')
		case '\t':
			buf = append(buf, '\\', 't')
		case '"':
			buf = append(buf, '\\', '"')
		case '\\':
			buf = append(buf, '\\', '\\')
		case '$', '%':
			buf = appendRune(buf, r)
			remain := s[i+1:]
			if len(remain) > 0 && remain[0] == '{' {
				// Double up our template introducer symbol to escape it.
				buf = appendRune(buf, r)
			}
		default:
			if !unicode.IsPrint(r) {
				var fmted string
				if r < 65536 {
					fmted = fmt.Sprintf("\\u%04x", r)
				} else {
					fmted = fmt.Sprintf("\\U%08x", r)
				}
				buf = append(buf, fmted...)
			} else {
				buf = appendRune(buf, r)
			}
		}
	}
	return buf
}

func appendRune(b []byte, r rune) []byte {
	l := utf8.RuneLen(r)
	for i := 0; i < l; i++ {
		b = append(b, 0) // make room at the end of our buffer
	}
	ch := b[len(b)-l:]
	utf8.EncodeRune(ch, r)
	return b
}
