package internal

import (
	"fmt"
	"io"
	"os"
	"regexp"
	"strconv"
	"strings"

	"github.com/fatih/color"
)

// this package contains all language agnostic utility funcs.

func String(str string) *string {
	return &str
}

func StringSlice(s []string) *[]string {
	return &s
}

func ToCamelCase(str string) string {
	return regexp.
		MustCompile("(^[A-Za-z])|_([A-Za-z])").
		ReplaceAllStringFunc(str, func(s string) string {
			return strings.ToUpper(strings.Replace(s, "_", "", -1))
		})
}

func ToLowerCamelCase(str string) string {
	first := true
	return regexp.
		MustCompile("(^[A-Za-z])|_([A-Za-z])").
		ReplaceAllStringFunc(str, func(s string) string {
			if first {
				first = false
				return strings.ToLower(strings.Replace(s, "_", "", -1))
			}
			return strings.ToUpper(strings.Replace(s, "_", "", -1))
		})
}

func ToStringLiterals(token []string) []string {
	r := []string{}

	for _, t := range token {
		r = append(r, ToStringLiteral(t))
	}

	return r
}

func ToStringLiteral(token string) string {
	return fmt.Sprintf(`"%s"`, token)
}

func AreAllNumbers(tokens ...string) bool {
	for _, token := range tokens {
		if _, err := strconv.Atoi(token); err != nil {
			return false
		}
	}

	return true
}

func ToNumberOrString(token string) string {
	if _, err := strconv.Atoi(token); err == nil {
		return token
	} else {
		return ToStringLiteral(token)
	}
}

// This is the main function use to write templates
func P(o io.Writer, args ...string) {
	for _, v := range args {
		o.Write([]byte(v))
	}

	o.Write([]byte("\n"))
}

func Fatal(message string) {
	color.Red("\n" + message + "\n")
	os.Exit(1)
}
