package user

import (
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"
	"time"
)

func validatePath(path string) error {
	_, err := os.Stat(path)
	if os.IsNotExist(err) {
		return nil
	}
	return fmt.Errorf("Path \"%v\" already exists, please provide a new path", path)
}

func validateExpiry(expiry string) error {
	if expiry == "_" {
		return nil
	}

	parts := strings.Split(expiry, ".")
	if !isValidDate(parts) {
		err := fmt.Errorf("Malformed expiry date string, use \"dd.mm.yy\"")
		return err
	}
	return nil
}

func validateStatus(status string) error {
	if status != "Blocked" && status != "Active" {
		err := fmt.Errorf("User status can only be \"Active\" or \"Blocked\"")
		return err
	}
	return nil
}

func validateLtype(ltype string) error {
	if ltype != "ini" && ltype != "first" && ltype != "last" {
		err := fmt.Errorf("Login type can only be \"ini\", \"first\" or \"last\"")
		return err
	}
	return nil
}

func validateGRR(grr string) error {
	// OK if empty, only "ini" login type requires it and we check :)
	if grr == "_" {
		return nil
	}

	users, err := getUsers()
	if err != nil {
		return err
	}

	isValid, _ := regexp.MatchString(`^\d{8}$`, grr) // is 8 digit number
	if !isValid {
		err := fmt.Errorf("Malformed GRR string, must be 8 digit number")
		return err
	}

	if grrExists(users, grr) {
		err := fmt.Errorf(`The informed GRR already exists in LDAP database
Note: To search for the account use "useradm user show -r %s"`, grr)
		return err
	}

	return nil
}

func validateGID(group string) error {
	var err error

	groups, err := getGroups()
	if err != nil {
		return err
	}

	for _, value := range groups {
		if value == group {
			return nil
		}
	}
	err = fmt.Errorf("Could't find group \"%v\" in LDAP database", group)
	return err
}

func validateUID(login string) error {
	users, err := getUsers()
	if err != nil {
		return err
	}
	res := searchUser(users, false, login, "", "", "", "", "")
	if len(res) != 0 {
		return fmt.Errorf(`The informed Login already exists in LDAP database
Note: To search for the account use "useradm user show -l %s"`, login)
	}
	return nil
}

func isValidDate(arr []string) bool {
	if len(arr) != 3 {
		return false
	}

	// convert to int
	day, err1 := strconv.Atoi(arr[0])
	mth, err2 := strconv.Atoi(arr[1])
	year, err3 := strconv.Atoi(arr[2])

	if err1 != nil || err2 != nil || err3 != nil {
		return false
	}

	// ensure year is two digits
	if year < 0 || year > 99 {
		return false
	}

	// validate the date
	fullYear := 2000 + year
	t := time.Date(fullYear, time.Month(mth), day, 0, 0, 0, 0, time.UTC)
	return t.Day() == day && t.Month() == time.Month(mth)
}

func ifThenElse(condition bool, a string, b string) string {
	if condition {
		return a
	}
	return b
}