package ru.zetit.bridgeandjoins.crypto;

import io.grpc.Status;
import io.grpc.stub.StreamObserver;
import ru.zetit.bridgeandjoins.crypto.v1.ActivateRequest;
import ru.zetit.bridgeandjoins.crypto.v1.ActivateResponse;
import ru.zetit.bridgeandjoins.crypto.v1.CryptoServiceGrpc;
import ru.zetit.bridgeandjoins.crypto.v1.HealthRequest;
import ru.zetit.bridgeandjoins.crypto.v1.HealthResponse;
import ru.zetit.bridgeandjoins.crypto.v1.ShutdownRequest;
import ru.zetit.bridgeandjoins.crypto.v1.ShutdownResponse;
import ru.zetit.bridgeandjoins.crypto.v1.SignRequest;
import ru.zetit.bridgeandjoins.crypto.v1.SignResponse;
import ru.zetit.bridgeandjoins.crypto.v1.VerifyRequest;
import ru.zetit.bridgeandjoins.crypto.v1.VerifyResponse;

/**
 * gRPC-биндинг: делегирует на хендлеры. Сам по себе не реализует
 * криптографию.
 */
public final class CryptoServiceImpl extends CryptoServiceGrpc.CryptoServiceImplBase {

    private final VerifyHandler verify;
    private final SignHandler sign;
    private final HealthHandler health;
    private final ActivateHandler activate;
    private final ShutdownHandler shutdown;

    public CryptoServiceImpl(VerifyHandler verify, SignHandler sign,
                             HealthHandler health, ActivateHandler activate,
                             ShutdownHandler shutdown) {
        this.verify = verify;
        this.sign = sign;
        this.health = health;
        this.activate = activate;
        this.shutdown = shutdown;
    }

    @Override
    public void verifyXMLDSig(VerifyRequest request, StreamObserver<VerifyResponse> obs) {
        try {
            obs.onNext(verify.handle(request));
            obs.onCompleted();
        } catch (Exception e) {
            obs.onError(Status.INTERNAL.withDescription(e.getMessage()).asException());
        }
    }

    @Override
    public void signXMLDSig(SignRequest request, StreamObserver<SignResponse> obs) {
        try {
            obs.onNext(sign.handle(request));
            obs.onCompleted();
        } catch (Exception e) {
            obs.onError(Status.INTERNAL.withDescription(e.getMessage()).asException());
        }
    }

    @Override
    public void health(HealthRequest request, StreamObserver<HealthResponse> obs) {
        obs.onNext(health.handle(request));
        obs.onCompleted();
    }

    @Override
    public void activate(ActivateRequest request, StreamObserver<ActivateResponse> obs) {
        try {
            obs.onNext(activate.handle(request));
            obs.onCompleted();
        } catch (Exception e) {
            obs.onError(Status.INTERNAL.withDescription(e.getMessage()).asException());
        }
    }

    @Override
    public void shutdown(ShutdownRequest request, StreamObserver<ShutdownResponse> obs) {
        try {
            obs.onNext(shutdown.handle(request));
            obs.onCompleted();
        } catch (Exception e) {
            obs.onError(Status.INTERNAL.withDescription(e.getMessage()).asException());
        }
    }
}
