tdlib-session-container/src/main/java/it/tdlight/reactiveapi/State.java

129 lines
4.5 KiB
Java

package it.tdlight.reactiveapi;
import static it.tdlight.reactiveapi.AuthPhase.AUTH_PHASE;
import static it.tdlight.reactiveapi.AuthPhase.BROKEN;
import static it.tdlight.reactiveapi.AuthPhase.LOGGED_IN;
import static it.tdlight.reactiveapi.AuthPhase.LOGGED_OUT;
import static it.tdlight.reactiveapi.AuthPhase.LOGGING_OUT;
import static it.tdlight.reactiveapi.AuthPhase.PARAMETERS_PHASE;
import io.soabase.recordbuilder.core.RecordBuilder;
import it.tdlight.common.Signal;
import it.tdlight.jni.TdApi;
import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@RecordBuilder
public record State(AuthPhase authPhase) implements StateBuilder.With {
private static final Logger LOG = LogManager.getLogger(State.class);
public State withSignal(Signal signal) {
var newState = this;
// Mark state as broken if the connection is errored unexpectedly
if (signal.isException()) {
newState = newState.withAuthPhase(BROKEN);
}
newState = switch (newState.authPhase) {
// Mark state as broken if the connection is terminated unexpectedly
case PARAMETERS_PHASE, AUTH_PHASE, LOGGED_IN -> {
if (signal.isClosed()) {
yield newState.withAuthPhase(BROKEN);
} else {
yield newState;
}
}
case LOGGING_OUT -> {
// Mark state as logged out if the connection is terminated successfully
if (signal.isClosed()) {
yield newState.withAuthPhase(LOGGED_OUT);
} else {
yield newState;
}
}
default -> newState;
};
if (newState.authPhase != BROKEN && signal.isUpdate()) {
var update = signal.getUpdate();
newState = switch (update.getConstructor()) {
// Forcefully logout if the update stream fails
case TdApi.Error.CONSTRUCTOR -> newState.withAuthPhase(LOGGED_OUT);
case TdApi.UpdateAuthorizationState.CONSTRUCTOR -> {
var updateAuthState = (TdApi.UpdateAuthorizationState) update;
yield switch (updateAuthState.authorizationState.getConstructor()) {
case TdApi.AuthorizationStateClosing.CONSTRUCTOR -> {
if (newState.authPhase != LOGGED_IN) {
LOG.warn("Logging out, but the current auth phase is {} instead of {}",
newState.authPhase,
Set.of(LOGGED_IN)
);
}
yield newState.withAuthPhase(LOGGING_OUT);
}
case TdApi.AuthorizationStateClosed.CONSTRUCTOR -> {
if (newState.authPhase != LOGGING_OUT) {
LOG.warn("Logged out, but the current auth phase is {} instead of {}",
newState.authPhase,
Set.of(LOGGING_OUT)
);
}
yield newState.withAuthPhase(LOGGED_OUT);
}
case TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR -> {
if (newState.authPhase != LOGGED_OUT) {
LOG.warn("Waiting parameters, but the current auth phase is {} instead of {}",
newState.authPhase,
Set.of(LOGGED_OUT)
);
}
yield newState.withAuthPhase(PARAMETERS_PHASE);
}
case TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR,
TdApi.AuthorizationStateWaitRegistration.CONSTRUCTOR,
TdApi.AuthorizationStateWaitCode.CONSTRUCTOR,
TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR,
TdApi.AuthorizationStateWaitOtherDeviceConfirmation.CONSTRUCTOR -> {
if (newState.authPhase != PARAMETERS_PHASE && newState.authPhase != AUTH_PHASE) {
LOG.warn(
"Waiting for authentication, but the current auth phase is {} instead of {}",
newState.authPhase,
Set.of(PARAMETERS_PHASE, AUTH_PHASE)
);
}
yield newState.withAuthPhase(AUTH_PHASE);
}
case TdApi.AuthorizationStateReady.CONSTRUCTOR -> {
if (newState.authPhase != PARAMETERS_PHASE && newState.authPhase != AUTH_PHASE) {
LOG.warn("Logged in, but the current auth phase is {} instead of {}",
newState.authPhase,
Set.of(PARAMETERS_PHASE, AUTH_PHASE)
);
}
yield newState.withAuthPhase(LOGGED_IN);
}
case TdApi.AuthorizationStateLoggingOut.CONSTRUCTOR -> {
if (newState.authPhase != LOGGED_IN) {
LOG.warn("Logged in, but the current auth phase is {} instead of {}",
newState.authPhase,
Set.of(LOGGED_IN)
);
}
yield newState.withAuthPhase(LOGGING_OUT);
}
default -> {
LOG.error("Unknown authorization state: {}", updateAuthState.authorizationState);
yield newState;
}
};
}
default -> newState;
};
}
return newState;
}
}