package adradius

import (
	"log"

	"git.paulbsd.com/paulbsd/adradius/src/config"
	auth "git.paulbsd.com/paulbsd/adradius/src/go-ad-auth"
	"layeh.com/radius"
	"layeh.com/radius/rfc2865"
)

// SetADRadiusConfig sets config of adradius
func SetADRadiusConfig(c *config.Config) (ldapconfig *auth.Config, err error) {
	var security auth.SecurityType

	if c.TLS {
		security = auth.SecurityTLS
	} else {
		security = auth.SecurityNone
	}

	ldapconfig = &auth.Config{
		Servers:    c.Servers,
		Port:       c.Port,
		BaseDN:     c.BaseDN,
		Security:   security,
		SkipVerify: c.SkipVerify,
	}

	return
}

// ADauth process authentication to Active Directory
func ADauth(ldapconfig *auth.Config, username string, password string) (status bool, err error) {
	status, err = auth.Authenticate(ldapconfig, username, password)
	if err != nil {
		return
	}
	if !status {
		return
	}
	return
}

// RunServer runs a new raduis server instance
func RunServer(config *config.Config, ldapconfig *auth.Config) {
	handler := func(w radius.ResponseWriter, r *radius.Request) {
		username := rfc2865.UserName_GetString(r.Packet)
		password := rfc2865.UserPassword_GetString(r.Packet)

		var code radius.Code

		status, _ := ADauth(ldapconfig, username, password)

		if status {
			code = radius.CodeAccessAccept
			log.Printf("Successful login for user %s", username)
		} else {
			code = radius.CodeAccessReject
			log.Printf("Failed login for user %s", username)
		}
		log.Printf("Writing %v to %v", code, r.RemoteAddr)
		w.Write(r.Response(code))
	}

	server := radius.PacketServer{
		Addr:         config.Listen,
		Handler:      radius.HandlerFunc(handler),
		SecretSource: radius.StaticSecretSource([]byte(config.Secret)),
	}

	log.Printf("Starting server on %s", config.Listen)
	if err := server.ListenAndServe(); err != nil {
		log.Fatal(err)
	}
}
