package common

import (
	"bufio"
	"crypto/rand"
	"encoding/base32"
	"encoding/binary"
	"fmt"
	"io"
	"math/big"
	"strings"
)

func AddStringSliceItem(item string, slice *[]string) {
	for _, i := range *slice {
		if i == item {
			return
		}
	}
	*slice = append(*slice, item)
}

func RemoveStringSliceItem(item string, slice *[]string) {
	for i, listItem := range *slice {
		if item == listItem {
			(*slice)[i] = (*slice)[len(*slice)-1]
			*slice = (*slice)[:len(*slice)-1]
		}
	}
}

func ResponseContainsSubstring(reader io.ReadCloser, target string) (bool, error) {
	scanner := bufio.NewScanner(reader)
	for scanner.Scan() {
		if strings.Contains(scanner.Text(), target) {
			return true, nil
		}
	}
	if err := scanner.Err(); err != nil {
		return false, err
	}
	return false, nil
}

var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")

// RandomID returns a random string of the given length.
func RandomID(length int) string {
	b := make([]rune, length)
	for i := range b {
		randInt, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
		b[i] = letters[randInt.Int64()]
	}

	return string(b)
}

func GetAccountNumFromAWSID(AWSID string) (string, error) {
	// Function to get the account number from an AWS ID (no verification required)
	// Source: https://medium.com/@TalBeerySec/a-short-note-on-aws-key-id-f88cc4317489
	if len(AWSID) < 4 {
		return "", fmt.Errorf("AWSID is too short")
	}
	if AWSID[4] == 'I' || AWSID[4] == 'J' {
		return "", fmt.Errorf("Can't get account number from AKIAJ/ASIAJ or AKIAI/ASIAI keys")
	}
	trimmedAWSID := AWSID[4:]
	decodedBytes, err := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(strings.ToUpper(trimmedAWSID))
	if err != nil {
		return "", err
	}

	if len(decodedBytes) < 6 {
		return "", fmt.Errorf("Decoded AWSID is too short")
	}

	data := make([]byte, 8)
	copy(data[2:], decodedBytes[0:6])
	z := binary.BigEndian.Uint64(data)
	const mask uint64 = 0x7fffffffff80
	accountNum := (z & mask) >> 7
	return fmt.Sprintf("%012d", accountNum), nil
}
