package ch.difty.sipamato.entity;

import java.time.LocalDateTime;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

public class Code extends SipamatoEntity {

    private static final long serialVersionUID = 1L;

    public static final String CODE_REGEX = "[1-9][A-Z]";

    public static final String CODE = "code";
    public static final String CODE_CLASS = "codeClass";
    public static final String NAME = "name";
    public static final String COMMENT = "comment";
    public static final String INTERNAL = "internal";
    public static final String SORT = "sort";

    @NotNull
    @Pattern(regexp = CODE_REGEX, message = "{code.invalidCode}")
    private final String code;

    @NotNull
    private final String name;

    private final String comment;

    private final boolean internal;

    @NotNull
    private final CodeClass codeClass;

    private final int sort;

    public Code(final String code, final String name, final String comment, final boolean internal, final Integer codeClassId, final String codeClassName, final String codeClassDescription,
            final int sort) {
        this(code, name, comment, internal, codeClassId, codeClassName, codeClassDescription, sort, null, null, null, null, null);
    }

    public Code(final String code, final String name, final String comment, final boolean internal, final Integer codeClassId, final String codeClassName, final String codeClassDescription,
            final int sort, final LocalDateTime created, final Integer createdBy, final LocalDateTime lastModified, final Integer lastModifiedBy, final Integer version) {
        this.code = code;
        this.name = name;
        this.comment = comment;
        this.internal = internal;
        if (codeClassId != null)
            this.codeClass = new CodeClass(codeClassId, codeClassName, codeClassDescription);
        else
            this.codeClass = null;
        this.sort = sort;
        setCreated(created);
        setCreatedBy(createdBy);
        setLastModified(lastModified);
        setLastModifiedBy(lastModifiedBy);
        setVersion(version != null ? version : 0);
    }

    public Code(final Code from) {
        this(from.code, from.name, from.comment, from.internal, new CodeClass(from.codeClass), from.sort, from.getCreated(), from.getCreatedBy(), from.getLastModified(), from.getLastModifiedBy(),
                from.getVersion());
    }

    private Code(final String code, final String name, final String comment, final boolean internal, final CodeClass codeClass, final int sort, final LocalDateTime created, final Integer createdBy,
            final LocalDateTime lastModified, final Integer lastModifiedBy, final Integer version) {
        this.code = code;
        this.name = name;
        this.comment = comment;
        this.internal = internal;
        this.codeClass = codeClass;
        this.sort = sort;
        setCreated(created);
        setCreatedBy(createdBy);
        setLastModified(lastModified);
        setLastModifiedBy(lastModifiedBy);
        setVersion(version);
    }

    public String getCode() {
        return code;
    }

    public String getName() {
        return name;
    }

    public String getComment() {
        return comment;
    }

    public boolean isInternal() {
        return internal;
    }

    public CodeClass getCodeClass() {
        return codeClass;
    }

    public int getSort() {
        return sort;
    }

    public String getDisplayValue() {
        final StringBuilder sb = new StringBuilder();
        sb.append(name);
        sb.append(" (").append(code).append(")");
        return sb.toString();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((code == null) ? 0 : code.hashCode());
        result = prime * result + ((codeClass == null) ? 0 : codeClass.hashCode());
        result = prime * result + ((comment == null) ? 0 : comment.hashCode());
        result = prime * result + (internal ? 1231 : 1237);
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + sort;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Code other = (Code) obj;
        if (code == null) {
            if (other.code != null)
                return false;
        } else if (!code.equals(other.code))
            return false;
        if (codeClass == null) {
            if (other.codeClass != null)
                return false;
        } else if (!codeClass.equals(other.codeClass))
            return false;
        if (comment == null) {
            if (other.comment != null)
                return false;
        } else if (!comment.equals(other.comment))
            return false;
        if (internal != other.internal)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (sort != other.sort)
            return false;
        return true;
    }

}

@@ -929,32 +929,41 @@
     public Code(
+@NotNull 
 final String cod
@@ -956,32 +956,41 @@
 nal String code,
+ @NotNull
  final String na
@@ -1030,32 +1030,41 @@
 oolean internal,
+ @NotNull
  final Integer c
@@ -1066,32 +1066,41 @@
 ger codeClassId,
+ @NotNull
  final String co
@@ -1103,32 +1103,53 @@
 g codeClassName,
+%0A            @NotNull
  final String co
@@ -1163,36 +1163,24 @@
 Description,
-%0A           
  final int s
@@ -1336,24 +1336,33 @@
 public Code(
+@NotNull 
 final String
@@ -1359,32 +1359,41 @@
 nal String code,
+ @NotNull
  final String na
@@ -1437,24 +1437,33 @@
 an internal,
+ @NotNull
  final Integ
@@ -1477,16 +1477,25 @@
 ClassId,
+ @NotNull
  final S
@@ -1510,24 +1510,45 @@
 deClassName,
+%0A            @NotNull
  final Strin
@@ -1570,28 +1570,16 @@
 ription,
-%0A           
  final i
@@ -1696,32 +1696,44 @@
  lastModifiedBy,
+%0A           
  final Integer v
@@ -2275,24 +2275,33 @@
 public Code(
+@NotNull 
 final Code f
@@ -2563,16 +2563,25 @@
 te Code(
+@NotNull 
 final St
@@ -2590,16 +2590,25 @@
 ng code,
+ @NotNull
  final S
@@ -2664,16 +2664,25 @@
 nternal,
+ @NotNull
  final C
@@ -2737,32 +2737,44 @@
 ateTime created,
+%0A           
  final Integer c
@@ -2778,36 +2778,24 @@
 r createdBy,
-%0A           
  final Local

@Nonnull should not be set to null