package ldap

import (
	"fmt"
	"log"

	"github.com/go-ldap/ldap/v3"
)

type TypesearchCount struct {
	ResultDest *int
	SearchLdap string
	LdapAttrs  []string
}

type TypesearchLdapValues struct {
	ResultDest *string
	SearchLdap string
	LdapAttrs  []string
}

func SearchLdapVal(l *ldap.Conn, search TypesearchLdapValues, attrValue string) {
	result, err := Search(l, search.SearchLdap, search.LdapAttrs)
	if err != nil {
		log.Fatal(err)
	}
	for _, entry := range result.Entries {
		for _, cn := range entry.GetAttributeValues(attrValue) {
			*search.ResultDest = cn
		}
	}
}

func SearchLdapCount(l *ldap.Conn, search TypesearchCount) {
	result, err := Search(l, search.SearchLdap, search.LdapAttrs)
	if err != nil {
		log.Fatal(err)
	}
	*search.ResultDest = len(result.Entries)
}

// Ldap Connection without TLS
func Connect(FQDN string, BindUsername string, BindPassword string) (*ldap.Conn, error) {
	// You can also use IP instead of FQDN
	l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:389", FQDN))
	l.Bind(BindUsername, BindPassword)
	if err != nil {
		return nil, err
	}

	return l, nil
}

// Normal Search
func Search(l *ldap.Conn, filter string, ldapAttrs []string) (*ldap.SearchResult, error) {

	searchReq := ldap.NewSearchRequest(
		"",
		ldap.ScopeWholeSubtree,
		0,
		0,
		0,
		false,
		filter,
		ldapAttrs,
		nil,
	)
	result, err := l.Search(searchReq)
	if err != nil {
		return nil, fmt.Errorf("error: %s", err)
	}

	if len(result.Entries) >= 0 {
		return result, nil
	} else {
		return nil, fmt.Errorf("couldn't fetch search entries")
	}
}
