package dev.dinauer.maven.maven.core.release;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import dev.dinauer.maven.maven.core.ArtifactId;
import dev.dinauer.maven.maven.core.Version;
import dev.dinauer.maven.user.User;
import jakarta.persistence.*;

import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Entity
@Table(name = "release_version")
public class ReleaseVersion implements Version
{
    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    private String id;

    @Column(name = "group_id_long")
    private String groupId;

    @Column(name = "artifact_id_long")
    private String artifactId;

    private String version;

    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "artifact_id")
    @JsonBackReference
    private ArtifactId artifact;

    @OneToMany(mappedBy = "releaseVersion", cascade = CascadeType.ALL)
    @JsonManagedReference
    private List<ReleaseJar> releaseJars = new ArrayList<>();

    @OneToOne(mappedBy = "releaseVersion", cascade = CascadeType.ALL)
    @JsonManagedReference
    private ReleasePom releasePom;

    @Column(name = "last_pulled")
    private ZonedDateTime lastPulled;

    @Column(name = "pull_count")
    private int pullCount = 0;

    @Column(name = "uploaded_by")
    private String uploadedBy;

    @Transient
    private User uploadUser;

    public String getId()
    {
        return id;
    }

    public ReleaseVersion setId(String id)
    {
        this.id = id;
        return this;
    }

    public String getGroupId()
    {
        return groupId;
    }

    public ReleaseVersion setGroupId(String groupId)
    {
        this.groupId = groupId;
        return this;
    }

    public String getArtifactId()
    {
        return artifactId;
    }

    public ReleaseVersion setArtifactId(String artifactId)
    {
        this.artifactId = artifactId;
        return this;
    }

    public String getVersion()
    {
        return version;
    }

    public ReleaseVersion setVersion(String version)
    {
        this.version = version;
        return this;
    }

    public ArtifactId getArtifact()
    {
        return artifact;
    }

    public ReleaseVersion setArtifact(ArtifactId artifactId)
    {
        this.artifact = artifactId;
        return this;
    }

    public List<ReleaseJar> getJars()
    {
        return releaseJars;
    }

    public ReleaseVersion setJars(List<ReleaseJar> releaseJars)
    {
        this.releaseJars = releaseJars;
        return this;
    }

    public ReleasePom getPom()
    {
        return releasePom;
    }

    public ReleaseVersion setPom(ReleasePom releasePom)
    {
        this.releasePom = releasePom;
        return this;
    }

    public ZonedDateTime getLastPulled()
    {
        return lastPulled;
    }

    public ReleaseVersion setLastPulled(ZonedDateTime lastPulled)
    {
        this.lastPulled = lastPulled;
        return this;
    }

    public String getUploadedBy()
    {
        return uploadedBy;
    }

    public ReleaseVersion setUploadedBy(String uploadedBy)
    {
        this.uploadedBy = uploadedBy;
        return this;
    }

    public User getUploadAccount()
    {
        return uploadUser;
    }

    public ReleaseVersion setUploadAccount(User uploadUser)
    {
        this.uploadUser = uploadUser;
        return this;
    }

    public int getPullCount()
    {
        return pullCount;
    }

    public ReleaseVersion setPullCount(int pullCount)
    {
        this.pullCount = pullCount;
        return this;
    }

    public void incrementPullCount()
    {
        pullCount = pullCount + 1;
    }

    public Optional<ReleaseJar> getJarByFilename(String filename)
    {
        for (ReleaseJar releaseJar : releaseJars)
        {
            if (releaseJar.getFilename().equals(filename))
            {
                return Optional.of(releaseJar);
            }
        }
        return Optional.empty();
    }

    @Override
    public boolean isSnapshot()
    {
        return false;
    }
}
