package stdlib

import (
	"fmt"

	"github.com/zclconf/go-cty/cty"
	"github.com/zclconf/go-cty/cty/convert"
	"github.com/zclconf/go-cty/cty/function"
)

var ConcatFunc = function.New(&function.Spec{
	Params: []function.Parameter{},
	VarParam: &function.Parameter{
		Name: "seqs",
		Type: cty.DynamicPseudoType,
	},
	Type: func(args []cty.Value) (ret cty.Type, err error) {
		if len(args) == 0 {
			return cty.NilType, fmt.Errorf("at least one argument is required")
		}

		if args[0].Type().IsListType() {
			// Possibly we're going to return a list, if all of our other
			// args are also lists and we can find a common element type.
			tys := make([]cty.Type, len(args))
			for i, val := range args {
				ty := val.Type()
				if !ty.IsListType() {
					tys = nil
					break
				}
				tys[i] = ty
			}

			if tys != nil {
				commonType, _ := convert.UnifyUnsafe(tys)
				if commonType != cty.NilType {
					return commonType, nil
				}
			}
		}

		etys := make([]cty.Type, 0, len(args))
		for i, val := range args {
			ety := val.Type()
			switch {
			case ety.IsTupleType():
				etys = append(etys, ety.TupleElementTypes()...)
			case ety.IsListType():
				if !val.IsKnown() {
					// We need to know the list to count its elements to
					// build our tuple type, so any concat of an unknown
					// list can't be typed yet.
					return cty.DynamicPseudoType, nil
				}

				l := val.LengthInt()
				subEty := ety.ElementType()
				for j := 0; j < l; j++ {
					etys = append(etys, subEty)
				}
			default:
				return cty.NilType, function.NewArgErrorf(
					i, "all arguments must be lists or tuples; got %s",
					ety.FriendlyName(),
				)
			}
		}
		return cty.Tuple(etys), nil
	},
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		switch {
		case retType.IsListType():
			// If retType is a list type then we know that all of the
			// given values will be lists and that they will either be of
			// retType or of something we can convert to retType.
			vals := make([]cty.Value, 0, len(args))
			for i, list := range args {
				list, err = convert.Convert(list, retType)
				if err != nil {
					// Conversion might fail because we used UnifyUnsafe
					// to choose our return type.
					return cty.NilVal, function.NewArgError(i, err)
				}

				it := list.ElementIterator()
				for it.Next() {
					_, v := it.Element()
					vals = append(vals, v)
				}
			}
			if len(vals) == 0 {
				return cty.ListValEmpty(retType.ElementType()), nil
			}

			return cty.ListVal(vals), nil
		case retType.IsTupleType():
			// If retType is a tuple type then we could have a mixture of
			// lists and tuples but we know they all have known values
			// (because our params don't AllowUnknown) and we know that
			// concatenating them all together will produce a tuple of
			// retType because of the work we did in the Type function above.
			vals := make([]cty.Value, 0, len(args))

			for _, seq := range args {
				// Both lists and tuples support ElementIterator, so this is easy.
				it := seq.ElementIterator()
				for it.Next() {
					_, v := it.Element()
					vals = append(vals, v)
				}
			}

			return cty.TupleVal(vals), nil
		default:
			// should never happen if Type is working correctly above
			panic("unsupported return type")
		}
	},
})

var RangeFunc = function.New(&function.Spec{
	VarParam: &function.Parameter{
		Name: "params",
		Type: cty.Number,
	},
	Type: function.StaticReturnType(cty.List(cty.Number)),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		var start, end, step cty.Value
		switch len(args) {
		case 1:
			if args[0].LessThan(cty.Zero).True() {
				start, end, step = cty.Zero, args[0], cty.NumberIntVal(-1)
			} else {
				start, end, step = cty.Zero, args[0], cty.NumberIntVal(1)
			}
		case 2:
			if args[1].LessThan(args[0]).True() {
				start, end, step = args[0], args[1], cty.NumberIntVal(-1)
			} else {
				start, end, step = args[0], args[1], cty.NumberIntVal(1)
			}
		case 3:
			start, end, step = args[0], args[1], args[2]
		default:
			return cty.NilVal, fmt.Errorf("must have one, two, or three arguments")
		}

		var vals []cty.Value

		if step == cty.Zero {
			return cty.NilVal, function.NewArgErrorf(2, "step must not be zero")
		}
		down := step.LessThan(cty.Zero).True()

		if down {
			if end.GreaterThan(start).True() {
				return cty.NilVal, function.NewArgErrorf(1, "end must be less than start when step is negative")
			}
		} else {
			if end.LessThan(start).True() {
				return cty.NilVal, function.NewArgErrorf(1, "end must be greater than start when step is positive")
			}
		}

		num := start
		for {
			if down {
				if num.LessThanOrEqualTo(end).True() {
					break
				}
			} else {
				if num.GreaterThanOrEqualTo(end).True() {
					break
				}
			}
			if len(vals) >= 1024 {
				// Artificial limit to prevent bad arguments from consuming huge amounts of memory
				return cty.NilVal, fmt.Errorf("more than 1024 values were generated; either decrease the difference between start and end or use a smaller step")
			}
			vals = append(vals, num)
			num = num.Add(step)
		}
		if len(vals) == 0 {
			return cty.ListValEmpty(cty.Number), nil
		}
		return cty.ListVal(vals), nil
	},
})

// Concat takes one or more sequences (lists or tuples) and returns the single
// sequence that results from concatenating them together in order.
//
// If all of the given sequences are lists of the same element type then the
// result is a list of that type. Otherwise, the result is a of a tuple type
// constructed from the given sequence types.
func Concat(seqs ...cty.Value) (cty.Value, error) {
	return ConcatFunc.Call(seqs)
}

// Range creates a list of numbers by starting from the given starting value,
// then adding the given step value until the result is greater than or
// equal to the given stopping value. Each intermediate result becomes an
// element in the resulting list.
//
// When all three parameters are set, the order is (start, end, step). If
// only two parameters are set, they are the start and end respectively and
// step defaults to 1. If only one argument is set, it gives the end value
// with start defaulting to 0 and step defaulting to 1.
//
// Because the resulting list must be fully buffered in memory, there is an
// artificial cap of 1024 elements, after which this function will return
// an error to avoid consuming unbounded amounts of memory. The Range function
// is primarily intended for creating small lists of indices to iterate over,
// so there should be no reason to generate huge lists with it.
func Range(params ...cty.Value) (cty.Value, error) {
	return RangeFunc.Call(params)
}
