package ru.yandex.qe.dispenser.domain.d;

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

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.jetbrains.annotations.Nullable;

@JsonIgnoreProperties(ignoreUnknown = true)
public class DeliveryStatusOperationDto {

    private final String operationId;
    private final String accountId;
    private final String providerId;
    @Nullable
    private final List<DeliveryStatusRequestedQuotasDto> requestedQuotas;
    private final Instant createDateTime;
    @Nullable
    private final Instant updateDateTime;
    private final DeliveryOperationStatusDto status;
    @Nullable
    private final String errorMessage;
    @Nullable
    private final DeliveryOperationErrorKindDto errorKind;
    @Nullable
    private final DeliverableMetaRequestDto meta;
    @Nullable
    private final DeliverableFolderOperationDto folderOperationLog;

    @JsonCreator
    public DeliveryStatusOperationDto(
            @JsonProperty("operationId") String operationId,
            @JsonProperty("accountId") @Nullable String accountId,
            @JsonProperty("providerId") String providerId,
            @JsonProperty("requestedQuotas") @Nullable List<DeliveryStatusRequestedQuotasDto> requestedQuotas,
            @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC")
            @JsonProperty("createDateTime") Instant createDateTime,
            @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC")
            @JsonProperty("updateDateTime") @Nullable Instant updateDateTime,
            @JsonProperty("status") DeliveryOperationStatusDto status,
            @JsonProperty("errorMessage") @Nullable String errorMessage,
            @JsonProperty("errorKind") @Nullable DeliveryOperationErrorKindDto errorKind,
            @JsonProperty("meta") @Nullable DeliverableMetaRequestDto meta,
            @JsonProperty("folderOperationLog") @Nullable DeliverableFolderOperationDto folderOperationLog
    ) {
        this.operationId = operationId;
        this.accountId = accountId;
        this.providerId = providerId;
        this.requestedQuotas = requestedQuotas;
        this.createDateTime = createDateTime;
        this.updateDateTime = updateDateTime;
        this.status = status;
        this.errorMessage = errorMessage;
        this.errorKind = errorKind;
        this.meta = meta;
        this.folderOperationLog = folderOperationLog;
    }

    public String getOperationId() {
        return operationId;
    }

    public String getAccountId() {
        return accountId;
    }

    public String getProviderId() {
        return providerId;
    }

    @Nullable
    public List<DeliveryStatusRequestedQuotasDto> getRequestedQuotas() {
        return requestedQuotas;
    }

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC")
    public Instant getCreateDateTime() {
        return createDateTime;
    }

    @Nullable
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC")
    public Instant getUpdateDateTime() {
        return updateDateTime;
    }

    public DeliveryOperationStatusDto getStatus() {
        return status;
    }

    @Nullable
    public String getErrorMessage() {
        return errorMessage;
    }

    @Nullable
    public DeliveryOperationErrorKindDto getErrorKind() {
        return errorKind;
    }

    @Nullable
    public DeliverableMetaRequestDto getMeta() {
        return meta;
    }

    @Nullable
    public DeliverableFolderOperationDto getFolderOperationLog() {
        return folderOperationLog;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        DeliveryStatusOperationDto that = (DeliveryStatusOperationDto) o;
        return Objects.equals(operationId, that.operationId) && Objects.equals(accountId, that.accountId)
                && Objects.equals(providerId, that.providerId) && Objects.equals(requestedQuotas, that.requestedQuotas)
                && Objects.equals(createDateTime, that.createDateTime) && Objects.equals(updateDateTime, that.updateDateTime)
                && status == that.status && Objects.equals(errorMessage, that.errorMessage) && errorKind == that.errorKind
                && Objects.equals(meta, that.meta) && Objects.equals(folderOperationLog, that.folderOperationLog);
    }

    @Override
    public int hashCode() {
        return Objects.hash(operationId, accountId, providerId, requestedQuotas, createDateTime, updateDateTime,
                status, errorMessage, errorKind, meta, folderOperationLog);
    }

    @Override
    public String toString() {
        return "DeliveryStatusOperationDto{" +
                "operationId='" + operationId + '\'' +
                ", accountId='" + accountId + '\'' +
                ", providerId='" + providerId + '\'' +
                ", requestedQuotas=" + requestedQuotas +
                ", createDateTime=" + createDateTime +
                ", updateDateTime=" + updateDateTime +
                ", status=" + status +
                ", errorMessage='" + errorMessage + '\'' +
                ", errorKind=" + errorKind +
                ", meta=" + meta +
                ", folderOperationLog=" + folderOperationLog +
                '}';
    }
}
