package com.infoclinika.pdx.domain;

import com.infoclinika.pdx.domain.dataset.Dataset;
import com.infoclinika.pdx.domain.sample.Sample;
import com.infoclinika.pdx.domain.user.UserAccount;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.validation.constraints.Pattern;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Represents projects domain model.
 */
@Entity
public class Project extends Annotation {

    @Column(name = "created")
    private Timestamp created;

    @Column(name = "last_modified")
    private Timestamp lastModified;

    @Column(name = "is_public", nullable = false, columnDefinition = "TINYINT(1)")
    private boolean isPublic;

    @OneToMany(mappedBy = "project")
    private List<Sample> samples;

    @ManyToOne
    @JoinColumn
    private UserAccount owner;

    @OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
    private List<Dataset> datasets = new ArrayList<>();

    @Column(name = "unit")
    private String unit;

    @Pattern(regexp="^DA\\d{7}$", message = "Invalid DA number format")
    @Column(name = "da_number", unique = true, length = 9)
    private String daNumber;

    public Project() {
    }

    public Project(String name) {
        super(name);
    }

    public List<Sample> getSamples() {
        return samples;
    }

    public void setSamples(List<Sample> samples) {
        this.samples = samples;
    }

    public UserAccount getOwner() {
        return owner;
    }

    public void setOwner(UserAccount owner) {
        this.owner = owner;
    }

    public List<Dataset> getDatasets() {
        return datasets;
    }

    public Timestamp getCreated() {
        return created;
    }

    public void setCreated(Timestamp created) {
        this.created = created;
    }

    public Timestamp getLastModified() {
        return lastModified;
    }

    public void setLastModified(Timestamp lastModified) {
        this.lastModified = lastModified;
    }

    public String getUnit() {
        return unit;
    }

    public void setUnit(String unit) {
        this.unit = unit;
    }

    public boolean isPublic() {
        return isPublic;
    }

    public void setPublic(boolean isPublic) {
        this.isPublic = isPublic;
    }

    public String getDaNumber() {
        return daNumber;
    }

    public void setDaNumber(String daNumber) {
        this.daNumber = daNumber;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        if (!super.equals(o)) {
            return false;
        }
        final Project project = (Project) o;
        return isPublic() == project.isPublic()
               && Objects.equals(getOwner(), project.getOwner());
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), isPublic(), getOwner());
    }

    @Override
    public String toString() {
        return "Project{"
               + "id=" + getId()
               + ", name='" + getName() + '\''
               + ", created=" + created
               + ", lastModified=" + lastModified
               + ", isPublic=" + isPublic
               + ", owner=" + owner
               + "}";
    }
}
