package utils

import (
	"strings"
)

func Ptr[T any](t T) *T {
	return &t
}

func GetContentWithIndent(indent int, content string) string {
	lines := strings.Split(content, "\n")
	lines[0] = strings.Repeat(" ", indent) + strings.TrimLeft(lines[0], " \t") // indent first line
	return strings.Join(lines, "\n"+strings.Repeat(" ", indent))               // indent all lines
}

func Any[T any](ts []T, fn func(T) bool) (bool, T) {
	for _, t := range ts {
		if fn(t) {
			return true, t
		}
	}
	var result T
	return false, result
}
func Map[T, V any](ts []T, fn func(t T) V) []V {
	vs := make([]V, len(ts))
	for i, t := range ts {
		vs[i] = fn(t)
	}
	return vs
}
func Filter[T any](ts []T, fn func(i int, t T) bool) []T {
	vs := make([]T, 0, len(ts))
	for i, t := range ts {
		if fn(i, t) {
			vs = append(vs, t)
		}
	}
	return vs
}
func ToMap[T, V any, K comparable](ts []T, keyFn func(i int, t T) K, valueFn func(i int, t T) V) map[K]V {
	vs := make(map[K]V, 0)
	for i, t := range ts {
		vs[keyFn(i, t)] = valueFn(i, t)
	}
	return vs
}

// Values returns the values of the map m.
// The values will be in an indeterminate order.
func Values[M ~map[K]V, K comparable, V any](m M) []V {
	r := make([]V, 0, len(m))
	for _, v := range m {
		r = append(r, v)
	}
	return r
}

// Values returns the values of the map m.
// The values will be in an indeterminate order.
func Merge[M ~map[K]V, K comparable, V any](m1, m2 M) map[K]V {
	m := make(map[K]V, len(m1)+len(m2))
	for k, v := range m1 {
		m[k] = v
	}
	for k, v := range m2 {
		m[k] = v
	}
	return m
}
