package com.rera.mss.model

import com.rera.mss.config.LONG_STRING_FIELD_LENGTH
import com.rera.mss.config.MEDIUM_STRING_FIELD_LENGTH
import com.rera.mss.config.SHORT_STRING_FIELD_LENGTH
import javax.persistence.*
import javax.validation.constraints.NotBlank
import javax.validation.constraints.Size


@Entity
@Table(name = "User")
data class User(
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        var id: Long = 0,

        @NotBlank
        @Size(max = SHORT_STRING_FIELD_LENGTH)
        @Column(unique = true)
        var username: String,

        @NotBlank
        @Size(max = MEDIUM_STRING_FIELD_LENGTH)
        @Column(unique = true)
        var email: String,

        @NotBlank
        @Size(max = LONG_STRING_FIELD_LENGTH)
        var password: String,

        @Size(max = MEDIUM_STRING_FIELD_LENGTH)
        @Column(name = "first_name")
        var firstName: String,

        @Size(max = MEDIUM_STRING_FIELD_LENGTH)
        @Column(name = "last_name")
        var lastName: String

) {
    @OneToMany(mappedBy = "user", cascade = [CascadeType.ALL], orphanRemoval = true)
    var userRoles: MutableSet<UserRole> = mutableSetOf()

    @OneToMany(mappedBy = "user", cascade = [CascadeType.ALL], orphanRemoval = true)
    var userInstruments: MutableSet<Instrument> = mutableSetOf()

    @OneToMany(mappedBy = "user", cascade = [CascadeType.ALL], orphanRemoval = true)
    var userInverters: MutableSet<Inverter> = mutableSetOf()

    @OneToMany(mappedBy = "user", cascade = [CascadeType.ALL], orphanRemoval = true)
    var userMonitoredAreas: MutableSet<MonitoredArea> = mutableSetOf()

    fun addRole(role: Role) {
        val userRole = UserRole(user = this, role = role)
        userRoles.add(userRole)
        role.userRoles.add(userRole)
    }

    fun addInstrument(ins: Instrument) {
        val userInstrument = Instrument(
                user = this,
                guid = ins.guid,
                gpsCoordinates = ins.gpsCoordinates,
                altitude = ins.altitude,
                tilt = ins.tilt,
                direction = ins.direction,
                calibrationValue = ins.calibrationValue,
                state = ins.state
        )

        userInstruments.add(userInstrument)
    }

    fun addInverter(inv: Inverter) {
        val userInverter = Inverter(
                user = this,
                manufacturer = inv.manufacturer,
                efficiency = inv.efficiency
        )
        userInverters.add(userInverter)

    }

    fun addMonitoredArea(ma: MonitoredArea) {
        val userMonitoredArea = MonitoredArea(
                user = this,
                inverter = ma.inverter,
                instrument = ma.instrument,
                description = ma.description
        )
        userMonitoredAreas.add(userMonitoredArea)

    }
}