// Copyright 2019 CUE 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 list contains functions for manipulating and examining lists.
package list

import (
	"fmt"
	"sort"

	"cuelang.org/go/cue"
	"cuelang.org/go/internal"
	"github.com/cockroachdb/apd/v2"
)

// Drop reports the suffix of list x after the first n elements,
// or [] if n > len(x).
//
// For instance:
//
//    Drop([1, 2, 3, 4], 2)
//
// results in
//
//    [3, 4]
//
func Drop(x []cue.Value, n int) ([]cue.Value, error) {
	if n < 0 {
		return nil, fmt.Errorf("negative index")
	}

	if n > len(x) {
		return []cue.Value{}, nil
	}

	return x[n:], nil
}

// Flatten reports a flattend sequence of the list xs by expanding any elements
// that are lists.
//
// For instance:
//
//    Flatten([1, [[2, 3], []], [4]])
//
// results in
//
//    [1, 2, 3, 4]
//
func Flatten(xs cue.Value) ([]cue.Value, error) {
	var flatten func(cue.Value) ([]cue.Value, error)
	flatten = func(xs cue.Value) ([]cue.Value, error) {
		var res []cue.Value
		iter, err := xs.List()
		if err != nil {
			return nil, err
		}
		for iter.Next() {
			val := iter.Value()
			if val.Kind() == cue.ListKind {
				vals, err := flatten(val)
				if err != nil {
					return nil, err
				}
				res = append(res, vals...)
			} else {
				res = append(res, val)
			}
		}
		return res, nil
	}
	return flatten(xs)
}

// FlattenN reports a flattend sequence of the list xs by expanding any elements
// depth levels deep. If depth is negative all elements are expanded.
//
// For instance:
//
//    FlattenN([1, [[2, 3], []], [4]], 1)
//
// results in
//
//    [1, [2, 3], [], 4]
//
func FlattenN(xs cue.Value, depth *internal.Decimal) ([]cue.Value, error) {
	var flattenN func(cue.Value, *internal.Decimal) ([]cue.Value, error)
	one := apd.New(1, 0)
	flattenN = func(xs cue.Value, depth *internal.Decimal) ([]cue.Value, error) {
		var res []cue.Value
		iter, err := xs.List()
		if err != nil {
			return nil, err
		}
		for iter.Next() {
			val := iter.Value()
			if val.Kind() == cue.ListKind && !depth.IsZero() {
				d := apd.New(0, 0)
				_, err := internal.BaseContext.Sub(d, depth, one)
				if err != nil {
					return nil, err
				}
				vals, err := flattenN(val, d)
				if err != nil {
					return nil, err
				}
				res = append(res, vals...)
			} else {
				res = append(res, val)
			}
		}
		return res, nil
	}
	return flattenN(xs, depth)
}

// Take reports the prefix of length n of list x, or x itself if n > len(x).
//
// For instance:
//
//    Take([1, 2, 3, 4], 2)
//
// results in
//
//    [1, 2]
//
func Take(x []cue.Value, n int) ([]cue.Value, error) {
	if n < 0 {
		return nil, fmt.Errorf("negative index")
	}

	if n > len(x) {
		return x, nil
	}

	return x[:n], nil
}

// Slice extracts the consecutive elements from list x starting from position i
// up till, but not including, position j, where 0 <= i < j <= len(x).
//
// For instance:
//
//    Slice([1, 2, 3, 4], 1, 3)
//
// results in
//
//    [2, 3]
//
func Slice(x []cue.Value, i, j int) ([]cue.Value, error) {
	if i < 0 {
		return nil, fmt.Errorf("negative index")
	}

	if i > j {
		return nil, fmt.Errorf("invalid index: %v > %v", i, j)
	}

	if i > len(x) {
		return nil, fmt.Errorf("slice bounds out of range")
	}

	if j > len(x) {
		return nil, fmt.Errorf("slice bounds out of range")
	}

	return x[i:j], nil
}

// MinItems reports whether a has at least n items.
func MinItems(a []cue.Value, n int) bool {
	return len(a) >= n
}

// MaxItems reports whether a has at most n items.
func MaxItems(a []cue.Value, n int) bool {
	return len(a) <= n
}

// UniqueItems reports whether all elements in the list are unique.
func UniqueItems(a []cue.Value) bool {
	b := []string{}
	for _, v := range a {
		b = append(b, fmt.Sprint(v))
	}
	sort.Strings(b)
	for i := 1; i < len(b); i++ {
		if b[i-1] == b[i] {
			return false
		}
	}
	return true
}

// Contains reports whether v is contained in a. The value must be a
// comparable value.
func Contains(a []cue.Value, v cue.Value) bool {
	for _, w := range a {
		if v.Equals(w) {
			return true
		}
	}
	return false
}
