package aoc

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strconv"
	"strings"
)

func ArgIsSet(a string) bool {
	for i := range os.Args {
		if os.Args[i] == a || strings.HasPrefix(os.Args[i], a+"=") {
			return true
		}
	}
	return false
}

func GetArgValue(a string) string {
	for i := range os.Args {
		if strings.HasPrefix(os.Args[i], a+"=") {
			return strings.TrimPrefix(os.Args[i], a+"=")
		}
	}
	return ""
}

func GetArgNumber(i int) string {
	if len(os.Args) > i {
		return os.Args[i]
	}
	return ""
}

func StdinToStringSlice() []string {
	var input []string
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input = append(input, scanner.Text())
	}
	return input
}

func Atoi(i string) int {
	var ret int
	var err error
	if ret, err = strconv.Atoi(i); err != nil {
		log.Fatal("Invalid Atoi")
	}
	return ret
}

func Itoa(i int) string {
	return strconv.Itoa(i)
}

func StdinToString() string {
	var input string
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input += scanner.Text()
	}
	return input
}

func FileToStringSlice(fn string) []string {
	return strings.Split(string(FileToBytes(fn)), "\n")
}

func FileToString(fn string) string {
	return string(FileToBytes(fn))
}

func FileToBytes(fn string) []byte {
	var c []byte
	var err error
	c, err = ioutil.ReadFile(fn)
	if err != nil {
		fmt.Println("Unable to read file: " + fn)
		os.Exit(1)
	}
	return c
}

func PrintProgress(curr, total int) {
	pct := int(float64(curr)/float64(total)) * 100
	for i := 0; i < 100; i += 10 {
		if pct > i {
			fmt.Print(FillChar)
		}
	}
}

func StringPermutations(str string) []string {
	perms := stringPermHelper(str, 0)
	var wrk []string
	// Now de-dupe
	for i := range perms {
		var found bool
		for j := range wrk {
			if wrk[j] == perms[i] {
				found = true
			}
		}
		if !found {
			wrk = append(wrk, perms[i])
		}
	}
	return wrk
}

func stringPermHelper(str string, i int) []string {
	ret := []string{str}
	if i != len(str) {
		r := []rune(str)
		for j := i; j < len(r); j++ {
			r[i], r[j] = r[j], r[i]
			ret = append(ret, stringPermHelper(string(r), i+1)...)
			r[i], r[j] = r[j], r[i]
		}
	}
	return ret
}

// Some character code stuff for prettier output
const (
	BorderNS = "\u2502"
	BorderWE = "\u2500"

	BorderNW = "\u250C"
	BorderNE = "\u2510"
	BorderSW = "\u2514"
	BorderSE = "\u2518"

	FillChar    = "\u2588"
	ClearScreen = "\033[H\033[2J"
)
