package com.atlassian.bitbucket.mesh.auth;

import com.atlassian.bitbucket.mesh.AbstractStatusException;
import com.atlassian.bitbucket.mesh.rpc.v1.RpcError;
import com.atlassian.bitbucket.mesh.rpc.v1.RpcErrorUtils;
import com.atlassian.bitbucket.mesh.rpc.v1.RpcInvalidPublicKey;
import com.atlassian.bitbucket.mesh.rpc.v1.RpcInvalidPublicKey.Reason;
import com.atlassian.bitbucket.mesh.rpc.v1.RpcPublicKey;
import io.grpc.Metadata;
import io.grpc.Status;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import static java.util.Objects.requireNonNull;

public class InvalidPublicKeyException extends AbstractStatusException {

    private final RpcPublicKey publicKey;
    private final Reason reason;

    public InvalidPublicKeyException(@Nonnull Reason reason, @Nonnull RpcPublicKey publicKey) {
        this(reason, publicKey, null);
    }

    public InvalidPublicKeyException(@Nonnull Reason reason, @Nonnull RpcPublicKey publicKey,
                                     @Nullable Throwable cause) {
        super("The provided public key is not valid: " + reason, cause, Status.INVALID_ARGUMENT);

        this.publicKey = requireNonNull(publicKey, "publicKey");
        this.reason = requireNonNull(reason, "reason");
    }

    @Nonnull
    public RpcPublicKey getPublicKey() {
        return publicKey;
    }

    @Override
    protected Metadata getTrailers() {
        return RpcErrorUtils.toMetadata(RpcError.newBuilder()
                .setInvalidPublicKey(RpcInvalidPublicKey.newBuilder()
                        .setPublicKey(publicKey)
                        .setReason(reason))
                .build());
    }
}
