package api

import (
	"fmt"
	"regexp"
	"strings"
	"unicode/utf8"
)

var emailRe = regexp.MustCompile(`^[^@\s]+@[^@\s.]+\.[^@\s]+$`)

const (
	maxShort = 200
	maxLong  = 4000
)

type fieldError struct {
	Field   string `json:"field"`
	Message string `json:"message"`
}

func (e fieldError) Error() string { return e.Field + ": " + e.Message }

func text(name, value string, required bool, max int) (string, *fieldError) {
	v := strings.TrimSpace(value)
	if v == "" {
		if required {
			return "", &fieldError{Field: name, Message: "This field is required."}
		}
		return "", nil
	}
	if utf8.RuneCountInString(v) > max {
		return "", &fieldError{
			Field:   name,
			Message: fmt.Sprintf("Keep this under %d characters.", max),
		}
	}
	return v, nil
}

func email(name, value string) (string, *fieldError) {
	v, err := text(name, value, true, maxShort)
	if err != nil {
		return "", err
	}
	v = strings.ToLower(v)
	if !emailRe.MatchString(v) {
		return "", &fieldError{Field: name, Message: "Enter an email address we can reply to."}
	}
	return v, nil
}

func oneOf(name, value string, allowed []string) (string, *fieldError) {
	v := strings.TrimSpace(value)
	for _, a := range allowed {
		if v == a {
			return v, nil
		}
	}
	return "", &fieldError{Field: name, Message: "Choose one of the listed options."}
}
