package com.ease.gsms.server.model;

import com.ease.gsms.server.model.util.MD5Hash;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Objects;

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)
public class Message {

    private Long id;

    private MD5Hash hash;

    private String fromICCID;

    private String to;

    private String content;

    private Date creationDate;

    private volatile Date allocationDate;

    private volatile Date sentDate;

    private volatile Date deliveredDate;

    private volatile Integer sendingStatus;

    private volatile Integer deliveryStatus;

    private Long dispatchRequestId;

    public Message(
            Long id,
            String fromICCID,
            String to,
            String content,
            Date creationDate,
            Date allocationDate,
            Date sentDate,
            Date deliveredDate,
            Integer sendingStatus,
            Integer deliveryStatus,
            Long dispatchRequestId
    ) {
        this.id = id;
        this.fromICCID = fromICCID;
        this.to = to;
        this.content = content;
        this.creationDate = creationDate;
        this.allocationDate = allocationDate;
        this.sentDate = sentDate;
        this.deliveredDate = deliveredDate;
        this.dispatchRequestId = dispatchRequestId;
        this.sendingStatus = sendingStatus;
        this.deliveryStatus = deliveryStatus;

        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(to.getBytes());
            digest.update(content.getBytes());
            hash = MD5Hash.fromBytes(digest.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    public Message(String to, String content, Long dispatchRequestId) {
        this(null, null, to, content, new Date(), null, null, null, 0, 0, dispatchRequestId);
    }

    public Message(String to, String content) {
        this(null, null, to, content, new Date(), null, null, null, 0, 0, null);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public MD5Hash getHash() {
        return hash;
    }

    public String getFromICCID() {
        return fromICCID;
    }

    public void setFromICCID(String fromICCID) {
        this.fromICCID = fromICCID;
    }

    public String getTo() {
        return to;
    }

    public String getContent() {
        return content;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public Date getAllocationDate() {
        return allocationDate;
    }

    public void setAllocationDate(Date allocationDate) {
        this.allocationDate = allocationDate;
    }

    public Date getSentDate() {
        return sentDate;
    }

    public void setSentDate(Date sentDate) {
        this.sentDate = sentDate;
    }

    public Date getDeliveredDate() {
        return deliveredDate;
    }

    public void setDeliveredDate(Date deliveredDate) {
        this.deliveredDate = deliveredDate;
    }

    public Integer getSendingStatus() {
        return sendingStatus;
    }

    public void setSendingStatus(Integer sendingStatus) {
        this.sendingStatus = sendingStatus;
    }

    public Integer getDeliveryStatus() {
        return deliveryStatus;
    }

    public void setDeliveryStatus(Integer deliveryStatus) {
        this.deliveryStatus = deliveryStatus;
    }

    public Long getDispatchRequestId() {
        return dispatchRequestId;
    }

    public void setDispatchRequestId(Long dispatchRequestId) {
        this.dispatchRequestId = dispatchRequestId;
    }

    public MessageStatus getStatus() {

        if (deliveredDate != null) {
            if (deliveryStatus == 1) {
                return MessageStatus.DELIVERED;
            } else {
                return MessageStatus.DELIVERY_FAILED;
            }
        } else if (sentDate != null) {
            if (sendingStatus == 1) {
                return MessageStatus.SENT;
            } else {
                return MessageStatus.SENDING_FAILED;
            }
        } else if (allocationDate != null) {
            return MessageStatus.ALLOCATED;
        } else {
            return MessageStatus.CREATED;
        }

    }

    public boolean isUnsent() {
        return
                getStatus().equals(MessageStatus.CREATED)
                        || getStatus().equals(MessageStatus.ALLOCATED)
                        || getStatus().equals(MessageStatus.RESERVED);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Message message = (Message) o;
        return Objects.equals(id, message.id) && Objects.equals(hash, message.hash) && Objects.equals(fromICCID, message.fromICCID) && Objects.equals(to, message.to) && Objects.equals(content, message.content) && Objects.equals(creationDate, message.creationDate) && Objects.equals(allocationDate, message.allocationDate) && Objects.equals(sentDate, message.sentDate) && Objects.equals(deliveredDate, message.deliveredDate) && Objects.equals(sendingStatus, message.sendingStatus) && Objects.equals(deliveryStatus, message.deliveryStatus) && Objects.equals(dispatchRequestId, message.dispatchRequestId);
    }

}
