package pki

import (
	"fmt"
	"io/ioutil"
	"math"
	"os"
	"path"
	"strconv"
	"strings"
)

const SymlinkPrefix = "_AUTH_ID_"

func GetCertificateAssociation(serial uint64) string {
	return fmt.Sprintf(SymlinkPrefix+"%0[2]*[1]X", serial, int(math.Ceil(math.Log2(float64(serial))/8)*2))
}

func GetAssociation(dirname string) (assocs string, err error) {
	return os.Readlink(dirname)
}

func GetAssociations(dirname string) (assocs []string, err error) {
	if ds, errr := ioutil.ReadDir(dirname); errr != nil {
		return nil, errr
	} else {
		for _, d := range ds {
			if d.Mode()&os.ModeSymlink == os.ModeSymlink {
				assocs = append(assocs, d.Name())
			}
		}
		return
	}
}

func GetTeamSerials(dirname string, id_team int64) (serials []uint64, err error) {
	// As futher comparaisons will be made with strings, convert it only one time
	str_tid := fmt.Sprintf("%d", id_team)

	var assocs []string
	if assocs, err = GetAssociations(dirname); err != nil {
		return
	} else {
		for _, assoc := range assocs {
			var tid string
			if tid, err = os.Readlink(path.Join(dirname, assoc)); err == nil && tid == str_tid && strings.HasPrefix(assoc, SymlinkPrefix) {
				if serial, err := strconv.ParseUint(assoc[9:], 16, 64); err == nil {
					serials = append(serials, serial)
				}
			}
		}
	}
	return
}

func GetTeamAssociations(dirname string, id_team int64) (teamAssocs []string, err error) {
	// As futher comparaisons will be made with strings, convert it only one time
	str_tid := fmt.Sprintf("%d", id_team)

	var assocs []string
	if assocs, err = GetAssociations(dirname); err != nil {
		return
	} else {
		for _, assoc := range assocs {
			var tid string
			if tid, err = os.Readlink(path.Join(dirname, assoc)); err == nil && tid == str_tid && !strings.HasPrefix(assoc, SymlinkPrefix) {
				teamAssocs = append(teamAssocs, assoc)
			}
		}
	}
	return
}

func DeleteTeamAssociation(dirname string, assoc string) error {
	if err := os.Remove(path.Join(dirname, assoc)); err != nil {
		return err
	}
	return nil
}
