package org.carlspring.strongbox.domain;

import org.carlspring.strongbox.artifact.ArtifactTag;
import org.carlspring.strongbox.artifact.coordinates.AbstractArtifactCoordinates;
import org.carlspring.strongbox.artifact.coordinates.ArtifactCoordinates;
import org.carlspring.strongbox.data.domain.GenericEntity;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import java.util.Date;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

/**
 * @author carlspring
 */
@Entity
public class ArtifactEntry
        extends GenericEntity
{

    private String storageId;

    private String repositoryId;

    // if you have to rename this field please update ArtifactEntryServiceImpl.findByCoordinates() implementation
    @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    private AbstractArtifactCoordinates artifactCoordinates;

    @ManyToMany(targetEntity = ArtifactTagEntry.class)
    private Set<ArtifactTag> tagSet;
    
    /**
     * This field is used as part of [storageId, repositoryId, artifactPath] unique index.
     */
    private String artifactPath;

    private Long sizeInBytes;

    private Date lastUpdated;

    private Date lastUsed;
    
    private Integer downloadCount = Integer.valueOf(0);

    public ArtifactEntry()
    {
    }

    public String getStorageId()
    {
        return storageId;
    }

    public void setStorageId(String storageId)
    {
        this.storageId = storageId;
    }

    public String getRepositoryId()
    {
        return repositoryId;
    }

    public void setRepositoryId(String repositoryId)
    {
        this.repositoryId = repositoryId;
    }

    public ArtifactCoordinates getArtifactCoordinates()
    {
        return artifactCoordinates;
    }

    public void setArtifactCoordinates(ArtifactCoordinates artifactCoordinates)
    {
        this.artifactCoordinates = (AbstractArtifactCoordinates) artifactCoordinates;
        getArtifactPath();
    }

    public Set<ArtifactTag> getTagSet()
    {
        return tagSet = Optional.ofNullable(tagSet).orElse(new HashSet<>());
    }

    protected void setTagSet(Set<ArtifactTag> tagSet)
    {
        this.tagSet = tagSet;
    }

    public final String getArtifactPath()
    {
        return artifactCoordinates == null ? artifactPath : (artifactPath = artifactCoordinates.toPath());
    }

    public void setArtifactPath(String artifactPath)
    {
        this.artifactPath = artifactCoordinates != null ? artifactCoordinates.toPath() : artifactPath;
    }

    public Long getSizeInBytes()
    {
        return sizeInBytes;
    }

    public void setSizeInBytes(Long sizeInBytes)
    {
        this.sizeInBytes = sizeInBytes;
    }

    public Date getLastUpdated()
    {
        return lastUpdated != null ? new Date(lastUpdated.getTime()) : null;
    }

    public void setLastUpdated(Date lastUpdated)
    {
        this.lastUpdated = lastUpdated != null ? new Date(lastUpdated.getTime()) : null;
    }

    public Date getLastUsed()
    {
        return lastUsed != null ? new Date(lastUsed.getTime()) : null;
    }

    public void setLastUsed(Date lastUsed)
    {
        this.lastUsed = lastUsed != null ? new Date(lastUsed.getTime()) : null;
    }

    public Integer getDownloadCount()
    {
        return downloadCount;
    }

    public void setDownloadCount(Integer downloadCount)
    {
        this.downloadCount = downloadCount;
    }

    @Override
    public String toString()
    {
        final StringBuilder sb = new StringBuilder("ArtifactEntry{");
        sb.append("\n\tstorageId='")
          .append(storageId)
          .append('\'');
        sb.append(", \n\trepositoryId='")
          .append(repositoryId)
          .append('\'');
        sb.append(", \n\tsizeInBytes='")
          .append(sizeInBytes)
          .append('\'');
        sb.append(", \n\tlastUpdated='")
          .append(lastUpdated)
          .append('\'');
        sb.append(", \n\tlastUsed='")
          .append(lastUsed)
          .append('\'');
        sb.append(", \n\tartifactCoordinates=")
          .append(artifactCoordinates);
        sb.append('}');
        return sb.toString();
    }
}

@@ -1321,16 +1321,43 @@
 astUsed;
+%0A%0A    private Date created;
 %0A    %0A  
@@ -3366,32 +3366,274 @@
  : null;%0A    %7D%0A%0A
+    public Date getCreated()%0A    %7B%0A        return created != null ? new Date(created.getTime()) : null;%0A    %7D%0A%0A    public void setCreated(Date created)%0A    %7B%0A        this.created = created != null ? new Date(created.getTime()) : null;%0A    %7D%0A%0A
     public Integ

Add created attribute with getters and setters