package co.sharptop.church

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString

@EqualsAndHashCode(includes = 'username')
@ToString(includes = 'username', includeNames = true, includePackage = false)
class Person implements Serializable {

    private static final long serialVersionUID = 1

    transient springSecurityService

    String username
    String password
    boolean enabled = true
    boolean accountExpired
    boolean accountLocked
    boolean passwordExpired

    Person(String username, String password) {
        this()
        this.username = username
        this.password = password
    }

    Set<Role> getAuthorities() {
        PersonRole.findAllByPerson(this)*.role
    }

    Boolean hasRole(Role role) {
        PersonRole.findAllByPerson(this).any { it.role == role }
    }

    def beforeInsert() {
        encodePassword()
    }

    def beforeUpdate() {
        if (isDirty('password')) {
            encodePassword()
        }
    }

    protected void encodePassword() {
        password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
    }

    static transients = ['springSecurityService']

    static constraints = {
        username blank: false, unique: true
        password blank: false
    }

    static mapping = {
        password column: '`password`'
    }

    static Person findOrCreate(String username) {
        Person.findByUsername(username) ?: createWithUsername(username)
    }

    private static Person createWithUsername(String username) {
        //TODO: generate a secure password or something.
        Person person = new Person(
            username: username,
            password:"badpassword",
            passwordExpired: true
        ).save(failOnError: true)

        new PersonRole(person: person, role: Role.findUser()).save(failOnError: true)

        return person
    }

}
