package auth

import (
	"bytes"
	"fmt"
	"os/exec"
	"regexp"
)

// creates a KerberosPrincipal for the user
func CreateKRBPrincipal(login string) error {
	cmd := exec.Command("kadmin.local", "-q",
		fmt.Sprintf("addprinc -policy padrao -randkey -x dn=uid=%s,ou=usuarios,dc=c3local %s", login, login))

	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("Failed to add Kerberos principal: %v\nOutput: %s", err, output)
	}

	return nil
}

// command that changes the password >:D
// the command kadmin.local returns 0 if the password
// change fails, bruh. so we have to check differently.
// in case you find another error message, please include it here :)
func ModKRBPassword(login, password string) error {
	cmd := exec.Command("kadmin.local", "-q",
		fmt.Sprintf("cpw -pw %s %s", password, login))

	var output bytes.Buffer
	cmd.Stdout = &output
	cmd.Stderr = &output

	err := cmd.Run()
	outStr := output.String()

	// made like this so it is easy to add more :]
	failPatt := []string{
		"does not contain enough character",
		"is too short",
	}

	for _, pattern := range failPatt {
		if match, _ := regexp.MatchString(pattern, outStr); match {
			return fmt.Errorf("Failed to change Kerberos password: \n%s", outStr)
		}
	}

	if err != nil {
		return fmt.Errorf("Password change failed: %v\nOutput:\n%s", err, outStr)
	}

	return nil
}

func DelKRBPrincipal(login string) error {
	cmd := exec.Command("kadmin.local", "-q", fmt.Sprintf("delprinc -force %s", login))

	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("Failed to delete Kerberos principal: %v\nOutput: %s", err, output)
	}

	return nil
}

func KRBRandKey(login string) error {
	cmd := exec.Command("kadmin.local", "-q", fmt.Sprintf("cpw -randkey %s", login))

	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("Failed to set randkey in Kerberos: %v\nOutput: %s", err, output)
	}

	return nil
}