package com.infoclinika.pdx.projection;

import com.infoclinika.pdx.domain.Project;
import com.infoclinika.pdx.domain.dataset.Dataset;
import com.infoclinika.pdx.domain.sample.SampleType;

import java.sql.Timestamp;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;

/**
 * Projection for private {@link Project} entity.
 */
public class ProjectDto {
    private final Long id;
    private final String name;
    private final Set<SampleType> models;
    private final Timestamp created;
    private final Timestamp lastModified;
    private final boolean isPublic;
    private final List<DatasetDto> datasets;

    /**
     * Initializes all fields.
     */
    public ProjectDto(Project project) {
        this.id = project.getId();
        this.name = project.getName();
        this.models = project.getDatasets().stream().map(Dataset::getModel).collect(toSet());
        this.created = project.getCreated();
        this.lastModified = project.getLastModified();
        this.isPublic = project.isPublic();
        this.datasets = project.getDatasets()
                               .stream()
                               .map(DatasetDto::new)
                               .collect(toList());
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Set<SampleType> getModels() {
        return models;
    }

    public Timestamp getCreated() {
        return created;
    }

    public Timestamp getLastModified() {
        return lastModified;
    }

    public boolean isPublic() {
        return isPublic;
    }

    public List<DatasetDto> getDatasets() {
        return datasets;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final ProjectDto that = (ProjectDto) o;
        return getId().equals(that.getId())
               && getName().equals(that.getName())
               && Objects.equals(getModels(), that.getModels())
               && Objects.equals(getCreated(), that.getCreated())
               && Objects.equals(getLastModified(), that.getLastModified())
               && isPublic() == that.isPublic();
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId(), getName(), getModels(), getCreated(), getLastModified(), isPublic());
    }

    @Override
    public String toString() {
        return "ProjectDto{"
               + "id=" + id
               + ", name='" + name + '\''
               + ", models=" + models
               + ", created=" + created
               + ", lastModified=" + lastModified
               + ", isPublic=" + isPublic
               + '}';
    }
}
