package ru.yandex.qe.dispenser.domain;

import java.time.Instant;
import java.util.Objects;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import ru.yandex.qe.dispenser.api.DtoBuilder;
import ru.yandex.qe.dispenser.api.v1.DiQuotaHistoryEvent;
import ru.yandex.qe.dispenser.domain.hierarchy.Hierarchy;

public class QuotaHistoryEvent extends HistoryEvent {
    private final long quotaId;
    private final Quota.Key quotaKey;
    private final long oldMax;
    private final long newMax;
    private final long oldOwnMax;
    private final long newOwnMax;
    private final String issueKey;

    public QuotaHistoryEvent(@Nullable final Long personId,
                             @Nullable final Long tvmId,
                             @NotNull final Instant updated,
                             @Nullable final String comment,
                             final long quotaId,
                             @NotNull final Quota.Key quotaKey,
                             final long oldMax,
                             final long newMax,
                             final long oldOwnMax,
                             final long newOwnMax,
                             @Nullable final String issueKey) {
        super(personId, tvmId, updated, comment);
        this.quotaId = quotaId;
        this.quotaKey = quotaKey;
        this.oldMax = oldMax;
        this.newMax = newMax;
        this.oldOwnMax = oldOwnMax;
        this.newOwnMax = newOwnMax;
        this.issueKey = issueKey;
    }

    public long getQuotaId() {
        return quotaId;
    }

    @NotNull
    public Quota.Key getQuotaKey() {
        return quotaKey;
    }

    public long getOldMax() {
        return oldMax;
    }

    public long getNewMax() {
        return newMax;
    }

    public long getOldOwnMax() {
        return oldOwnMax;
    }

    public long getNewOwnMax() {
        return newOwnMax;
    }

    @Nullable
    public String getIssueKey() {
        return issueKey;
    }

    public DiQuotaHistoryEvent toView() {
        final Long personId = getPersonId();
        String login = null;
        if (personId != null) {
            final Person person = Hierarchy.get().getPersonReader().read(personId);
            login = person.getLogin();
        }
        return DiQuotaHistoryEvent.builder()
                .id(getId())
                .tvmId(getTvmId())
                .person(login)
                .updated(getUpdated())
                .comment(getComment())
                .quotaKey(quotaKey.toView())
                .oldMax(oldMax)
                .newMax(newMax)
                .oldOwnMax(oldOwnMax)
                .newOwnMax(newOwnMax)
                .issueKey(issueKey)
                .build();
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        if (!super.equals(o)) {
            return false;
        }
        final QuotaHistoryEvent that = (QuotaHistoryEvent) o;
        return quotaId == that.quotaId &&
                oldMax == that.oldMax &&
                newMax == that.newMax &&
                oldOwnMax == that.oldOwnMax &&
                newOwnMax == that.newOwnMax &&
                Objects.equals(quotaKey, that.quotaKey) &&
                Objects.equals(issueKey, that.issueKey);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), quotaId, quotaKey, oldMax, newMax, oldOwnMax, newOwnMax, issueKey);
    }

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder implements DtoBuilder<QuotaHistoryEvent> {
        private Long id;
        private Long personId;
        private Long tvmId;
        private Instant updated;
        private String comment;
        private long quotaId;
        private Quota.Key quotaKey;
        private long oldMax;
        private long newMax;
        private long oldOwnMax;
        private long newOwnMax;
        private String issueKey;

        public Builder id(final Long id) {
            this.id = id;
            return this;
        }

        public Builder personId(final Long personId) {
            this.personId = personId;
            return this;

        }

        public Builder tvmId(final Long tvmId) {
            this.tvmId = tvmId;
            return this;
        }

        public Builder updated(final Instant updated) {
            this.updated = updated;
            return this;
        }

        public Builder comment(final String comment) {
            this.comment = comment;
            return this;
        }


        public Builder quotaId(final long quotaId) {
            this.quotaId = quotaId;
            return this;
        }


        public Builder quotaKey(final Quota.Key quotaKey) {
            this.quotaKey = quotaKey;
            return this;
        }

        public Builder oldMax(final long oldMax) {
            this.oldMax = oldMax;
            return this;
        }

        public Builder newMax(final long newMax) {
            this.newMax = newMax;
            return this;
        }

        public Builder oldOwnMax(final long oldOwnMax) {
            this.oldOwnMax = oldOwnMax;
            return this;
        }

        public Builder newOwnMax(final long newOwnMax) {
            this.newOwnMax = newOwnMax;
            return this;
        }

        public Builder issueKey(final String issueKey) {
            this.issueKey = issueKey;
            return this;
        }

        @NotNull
        @Override
        public QuotaHistoryEvent build() {
            final QuotaHistoryEvent quotaHistoryEvent = new QuotaHistoryEvent(personId, tvmId, updated, comment, quotaId, quotaKey, oldMax, newMax, oldOwnMax, newOwnMax, issueKey);
            if (id != null) {
                quotaHistoryEvent.setId(id);
            }
            return quotaHistoryEvent;
        }
    }
}
