package lib

import (
	"archive/tar"
	"bufio"
	"compress/gzip"
	"fmt"
	"io"
	"strings"
	"time"

	"github.com/gofiber/fiber/v2"
)

// configparser can't get multiple keys, so heres a function to manually extract them
func GetMultiple(k string, r io.Reader) ([]string, error) {
	var (
		res     []string
		value   string
		scanner *bufio.Scanner
	)

	scanner = bufio.NewScanner(r)

	for scanner.Scan() {
		line := scanner.Text()
		value = strings.TrimPrefix(line, fmt.Sprintf("%s = ", k))
		value = strings.TrimPrefix(value, fmt.Sprintf("%s =", k))
		value = strings.TrimPrefix(value, fmt.Sprintf("%s= ", k))
		value = strings.TrimPrefix(value, fmt.Sprintf("%s=", k))

		if line == value {
			continue
		}

		res = append(res, value)
	}

	return res, nil
}

func GetFiles(r io.Reader) ([]string, error) {
	var (
		gzip_reader io.Reader
		header      *tar.Header
		result      []string
		err         error
	)

	if gzip_reader, err = gzip.NewReader(r); err != nil {
		return result, err
	}

	reader := tar.NewReader(gzip_reader)

	for header, err = reader.Next(); err == nil; header, err = reader.Next() {
		if header.Typeflag != tar.TypeReg {
			continue
		}

		result = append(result, header.Name)
	}

	return result, nil
}

func ListToStr(l []string) string {
	res := ""
	for _, e := range l {
		res += e + " "
	}
	return res
}

func RenderError(c *fiber.Ctx, code int) error {
	var msg string = "Server Error"
	c.Status(code)

	switch code {
	case 404:
		msg = "Not Found"
	}

	return c.Render("error", fiber.Map{
		"msg": msg,
	})
}

func SizeFromBytes(size int64) string {
	if size > 1024*1024*1024 {
		return fmt.Sprintf("%dGB", (size / 1024 / 1024 / 1024))
	} else if size > 1024*1024 {
		return fmt.Sprintf("%dMB", (size / 1024 / 1024))
	} else if size > 1024 {
		return fmt.Sprintf("%dKB", (size / 1024))
	}
	return fmt.Sprintf("%dB", size)
}

func TimePassed(t time.Time) string {
	diff := time.Since(t)
	res := fmt.Sprintf(
		"%ds ago",
		int(diff.Seconds()),
	)

	if diff.Minutes() > 1 {
		res = fmt.Sprintf(
			"%dm and %ds ago",
			int(diff.Minutes()), int(diff.Seconds())-(int(diff.Minutes())*60),
		)
	}

	if diff.Hours() > 1 {
		res = fmt.Sprintf("%dh and %dm ago",
			int(diff.Hours()),
			int(diff.Minutes())-(int(diff.Hours())*60),
		)
	}

	return res
}

func SanitizeXSS(s string) string {
	var bad []string = []string{"~", "'", "\"", "/", "<", ">", "?", "=", "#", "(", ")", "{", "}", "*", "!", "`", "[", "]"}

	for _, c := range bad {
		s = strings.ReplaceAll(s, c, "")
	}

	return s
}