package io.delphiplatform.api.v2.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Objects;

import javax.validation.Valid;

/**
 * AuthTokenResponseBody
 */
@Validated
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AuthTokenResponseBody {

    @JsonProperty("access_token")
    private String accessToken = null;

    @JsonProperty("scope")
    private String scope = null;

    @JsonProperty("expires_in")
    private Long expiresIn = null;

    @JsonProperty("expires_at")
    private Long expiresAt = null;

    @JsonProperty("token_type")
    private String tokenType = null;

    public void calculateExpiresAt() {
        if (this.expiresIn != null) {
            LocalDateTime future = LocalDateTime.now().plusSeconds(this.expiresIn);
            this.setExpiresAt(future.toEpochSecond(ZoneOffset.UTC));
        }
    }

    public AuthTokenResponseBody accessToken(String accessToken) {
        this.accessToken = accessToken;
        return this;
    }

    /**
     * Get accessToken
     *
     * @return accessToken
     **/
    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public AuthTokenResponseBody scope(String scope) {
        this.scope = scope;
        return this;
    }

    /**
     * After authorizing, the available scopes are returned in a standard space deliminated format.
     *
     * @return scope
     **/
    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public AuthTokenResponseBody expiresIn(Long expiresIn) {
        this.expiresIn = expiresIn;
        return this;
    }

    /**
     * Length in seconds until token expiration.
     *
     * @return expiresIn
     **/
    @Valid
    public Long getExpiresIn() {
        return expiresIn;
    }

    public void setExpiresIn(Long expiresIn) {
        this.expiresIn = expiresIn;
    }

    public AuthTokenResponseBody expiresAt(Long expiresAt) {
        this.expiresAt = expiresAt;
        return this;
    }

    /**
     * The timestamp of the token expiration in the (Unix) epoch format.
     *
     * @return expiresAt
     **/
    @Valid
    public Long getExpiresAt() {
        return expiresAt;
    }

    public void setExpiresAt(Long expiresAt) {
        this.expiresAt = expiresAt;
    }

    public AuthTokenResponseBody tokenType(String tokenType) {
        this.tokenType = tokenType;
        return this;
    }

    /**
     * The token type, currently the only implementation is for `Bearer`.
     *
     * @return tokenType
     **/
    public String getTokenType() {
        return tokenType;
    }

    public void setTokenType(String tokenType) {
        this.tokenType = tokenType;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        AuthTokenResponseBody authTokenResponseBody = (AuthTokenResponseBody) o;
        return Objects.equals(this.accessToken, authTokenResponseBody.accessToken) &&
            Objects.equals(this.scope, authTokenResponseBody.scope) &&
            Objects.equals(this.expiresIn, authTokenResponseBody.expiresIn) &&
            Objects.equals(this.expiresAt, authTokenResponseBody.expiresAt) &&
            Objects.equals(this.tokenType, authTokenResponseBody.tokenType);
    }

    @Override
    public int hashCode() {
        return Objects.hash(accessToken, scope, expiresIn, expiresAt, tokenType);
    }

    @Override
    public String toString() {

        return "class AuthTokenResponseBody {\n" +
            "    accessToken: " + toIndentedString(accessToken) + "\n" +
            "    scope: " + toIndentedString(scope) + "\n" +
            "    expiresIn: " + toIndentedString(expiresIn) + "\n" +
            "    expiresAt: " + toIndentedString(expiresAt) + "\n" +
            "    tokenType: " + toIndentedString(tokenType) + "\n" +
            "}";
    }

    /**
     * Convert the given object to string with each line indented by 4 spaces (except the first line).
     */
    private String toIndentedString(Object o) {
        if (o == null) {
            return "null";
        }
        return o.toString().replace("\n", "\n    ");
    }
}
