package com.oguerreiro.resilient.security.resillient;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.oguerreiro.resilient.domain.AbstractResilientLongIdEntity;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

/**
 * SecurityGroup
 */
@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name = "security_group")
public class SecurityGroup extends AbstractResilientLongIdEntity<SecurityGroup> {
  private static final long serialVersionUID = 1L;

  /**
   * User defined code. Must be unique.
   */
  @NotNull
  @Size(min = 3)
  @Column(name = "code", nullable = false, unique = true)
  private String code;

  /**
   * Description.
   */
  @NotNull
  @Size(min = 3)
  @Column(name = "name")
  private String name;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "securityGroup", cascade = CascadeType.ALL, orphanRemoval = true)
  @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
  @JsonIgnoreProperties(value = { "securityGroup" }, allowSetters = true)
  private List<SecurityGroupPermission> securityGroupPermissions = new ArrayList<>();

  public String getCode() {
    return code;
  }

  public SecurityGroup code(String code) {
    this.setCode(code);
    return this;
  }

  public void setCode(String code) {
    this.code = code;
  }

  public List<SecurityGroupPermission> getSecurityGroupPermissions() {
    return securityGroupPermissions;
  }

  public SecurityGroup securityGroupPermissions(List<SecurityGroupPermission> securityGroupPermissions) {
    this.setSecurityGroupPermissions(securityGroupPermissions);
    return this;
  }

  public void setSecurityGroupPermissions(List<SecurityGroupPermission> securityGroupPermissions) {
    if (this.securityGroupPermissions != null) {
      this.securityGroupPermissions.forEach((v) -> v.setSecurityGroup(null));
    }
    if (securityGroupPermissions != null) {
      securityGroupPermissions.forEach((v) -> v.setSecurityGroup(this));
    }
    this.securityGroupPermissions = securityGroupPermissions;
  }

  public SecurityGroup addSecurityGroupPermission(SecurityGroupPermission securityGroupPermission) {
    this.securityGroupPermissions.add(securityGroupPermission);
    securityGroupPermission.setSecurityGroup(this);
    return this;
  }

  public SecurityGroup removeSecurityGroupPermission(SecurityGroupPermission securityGroupPermission) {
    this.securityGroupPermissions.remove(securityGroupPermission);
    securityGroupPermission.setSecurityGroup(null);
    return this;
  }

  public String getName() {
    return name;
  }

  public SecurityGroup name(String name) {
    this.setName(name);
    return this;
  }

  public void setName(String name) {
    this.name = name;
  }

  //@formatter:off
  @Override
  public String toString() {
    return "SecurityGroup{" + 
              "id=" + getId() + 
              ", code='" + getCode() + "'" + 
              ", name='" + getName() + "'" +
              ", version=" + getVersion()
        + "}";
  }
  //@formatter:on
}
