<commit_before>package org.hisp.dhis.android.core.sms.domain.interactor;

import org.hisp.dhis.android.core.common.BaseDataModel;
import org.hisp.dhis.android.core.common.State;
import org.hisp.dhis.android.core.enrollment.Enrollment;
import org.hisp.dhis.android.core.event.Event;
import org.hisp.dhis.android.core.sms.domain.converter.Converter;
import org.hisp.dhis.android.core.sms.domain.converter.Converter.DataToConvert;
import org.hisp.dhis.android.core.sms.domain.converter.EnrollmentConverter;
import org.hisp.dhis.android.core.sms.domain.converter.EventConverter;
import org.hisp.dhis.android.core.sms.domain.repository.DeviceStateRepository;
import org.hisp.dhis.android.core.sms.domain.repository.LocalDbRepository;
import org.hisp.dhis.android.core.sms.domain.repository.SmsRepository;
import org.hisp.dhis.android.core.sms.domain.utils.Pair;
import org.hisp.dhis.android.core.trackedentity.TrackedEntityAttributeValue;
import org.hisp.dhis.android.core.trackedentity.TrackedEntityDataValue;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.Single;

public class SmsSubmitCase {
    private final static int SENDING_TIMEOUT = 120;
    private final LocalDbRepository localDbRepository;
    private final SmsRepository smsRepository;
    private final DeviceStateRepository deviceStateRepository;

    public SmsSubmitCase(LocalDbRepository localDbRepository, SmsRepository smsRepository,
                         DeviceStateRepository deviceStateRepository) {
        this.localDbRepository = localDbRepository;
        this.smsRepository = smsRepository;
        this.deviceStateRepository = deviceStateRepository;
    }

    public void acceptSMSCount(boolean accept) {
        smsRepository.acceptSMSCount(accept);
    }

    public Observable<SmsRepository.SmsSendingState> submit(final Event event,
                                                            final List<TrackedEntityDataValue>
                                                                    values) {
        return submit(new EventConverter(),
                new EventConverter.EventData(event, values));
    }

    public Observable<SmsRepository.SmsSendingState> submit(final Enrollment enrollment,
                                                            final String trackedEntityType,
                                                            final Collection<TrackedEntityAttributeValue>
                                                                    attributes) {
        return Single.zip(
                localDbRepository.getMetadataIds(),
                localDbRepository.getUserName(),
                Pair::create
        ).flatMapObservable(pair -> submit(
                new EnrollmentConverter(pair.first),
                new EnrollmentConverter.EnrollmentData(enrollment, trackedEntityType, attributes, pair.second)
        ));
    }

    public <T extends DataToConvert> Observable<SmsRepository.SmsSendingState>
    submit(final Converter<T> converter, final T dataItem) {
        return checkPreconditions()
                .andThen(Single.zip(
                        localDbRepository.getGatewayNumber(),
                        converter.format(dataItem),
                        Pair::create)
                ).flatMapObservable(numAndContents ->
                        smsRepository.sendSms(numAndContents.first, numAndContents.second, SENDING_TIMEOUT))
                .flatMap(smsSendingState -> {
                    if (SmsRepository.State.ALL_SENT.equals(smsSendingState.getState())) {
                        return localDbRepository.updateSubmissionState(dataItem.getDataModel(), State.SENT_VIA_SMS)
                                .andThen(Observable.just(smsSendingState));
                    }
                    return Observable.just(smsSendingState);
                });
    }

    public <T extends BaseDataModel> Completable checkConfirmationSms(final Collection<String> requiredTexts,
                                                                      final T dataModel) {
        return Single.zip(localDbRepository.getConfirmationSenderNumber(),
                Single.just(requiredTexts),
                localDbRepository.getWaitingResultTimeout(),
                ResultCheckData::create
        ).flatMapCompletable(config ->
                smsRepository.listenToConfirmationSms(
                        config.waitingResultTimeout, config.confirmationSenderNumber, config.requiredStrings))
                .andThen(localDbRepository.updateSubmissionState(dataModel, State.SYNCED_VIA_SMS));
    }

    private Completable checkPreconditions() {
        ArrayList<Single<Boolean>> checks = new ArrayList<>();
        checks.add(deviceStateRepository.hasCheckNetworkPermission());
        checks.add(deviceStateRepository.hasReceiveSMSPermission());
        checks.add(deviceStateRepository.hasSendSMSPermission());
        checks.add(deviceStateRepository.isNetworkConnected());
        checks.add(localDbRepository.getGatewayNumber().map(number -> number.length() > 0));
        checks.add(localDbRepository.getUserName().map(username -> username.length() > 0));

        return Single.merge(checks).flatMapCompletable(checkPassed -> {
            if (!checkPassed) {
                return Completable.error(new PreconditionFailed());
            }
            return Completable.complete();
        });
    }

    private static class ResultCheckData {
        String confirmationSenderNumber;
        Collection<String> requiredStrings;
        int waitingResultTimeout;

        private ResultCheckData() {
        }

        static ResultCheckData create(String confirmationSenderNumber,
                                      Collection<String> requiredStrings,
                                      int waitingResultTimeout) {
            ResultCheckData data = new ResultCheckData();
            data.confirmationSenderNumber = confirmationSenderNumber;
            data.requiredStrings = requiredStrings;
            data.waitingResultTimeout = waitingResultTimeout;
            return data;
        }
    }
<commit_msg>Updated reading sms result<commit_after>package org.hisp.dhis.android.core.sms.domain.interactor;

import org.hisp.dhis.android.core.common.BaseDataModel;
import org.hisp.dhis.android.core.common.State;
import org.hisp.dhis.android.core.enrollment.Enrollment;
import org.hisp.dhis.android.core.event.Event;
import org.hisp.dhis.android.core.sms.domain.converter.Converter;
import org.hisp.dhis.android.core.sms.domain.converter.Converter.DataToConvert;
import org.hisp.dhis.android.core.sms.domain.converter.EnrollmentConverter;
import org.hisp.dhis.android.core.sms.domain.converter.EventConverter;
import org.hisp.dhis.android.core.sms.domain.repository.DeviceStateRepository;
import org.hisp.dhis.android.core.sms.domain.repository.LocalDbRepository;
import org.hisp.dhis.android.core.sms.domain.repository.SmsRepository;
import org.hisp.dhis.android.core.sms.domain.utils.Pair;
import org.hisp.dhis.android.core.trackedentity.TrackedEntityAttributeValue;
import org.hisp.dhis.android.core.trackedentity.TrackedEntityDataValue;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.Single;

public class SmsSubmitCase {
    private final static int SENDING_TIMEOUT = 120;
    private final LocalDbRepository localDbRepository;
    private final SmsRepository smsRepository;
    private final DeviceStateRepository deviceStateRepository;

    public SmsSubmitCase(LocalDbRepository localDbRepository, SmsRepository smsRepository,
                         DeviceStateRepository deviceStateRepository) {
        this.localDbRepository = localDbRepository;
        this.smsRepository = smsRepository;
        this.deviceStateRepository = deviceStateRepository;
    }

    public void acceptSMSCount(boolean accept) {
        smsRepository.acceptSMSCount(accept);
    }

    public Observable<SmsRepository.SmsSendingState> submit(final Event event,
                                                            final List<TrackedEntityDataValue>
                                                                    values) {
        return submit(new EventConverter(),
                new EventConverter.EventData(event, values));
    }

    public Observable<SmsRepository.SmsSendingState> submit(final Enrollment enrollment,
                                                            final String trackedEntityType,
                                                            final Collection<TrackedEntityAttributeValue>
                                                                    attributes) {
        return Single.zip(
                localDbRepository.getMetadataIds(),
                localDbRepository.getUserName(),
                Pair::create
        ).flatMapObservable(pair -> submit(
                new EnrollmentConverter(pair.first),
                new EnrollmentConverter.EnrollmentData(enrollment, trackedEntityType, attributes, pair.second)
        ));
    }

    public <T extends DataToConvert> Observable<SmsRepository.SmsSendingState>
    submit(final Converter<T> converter, final T dataItem) {
        return checkPreconditions()
                .andThen(Single.zip(
                        localDbRepository.getGatewayNumber(),
                        converter.format(dataItem),
                        Pair::create)
                ).flatMapObservable(numAndContents ->
                        smsRepository.sendSms(numAndContents.first, numAndContents.second, SENDING_TIMEOUT))
                .flatMap(smsSendingState -> {
                    if (SmsRepository.State.ALL_SENT.equals(smsSendingState.getState())) {
                        return localDbRepository.updateSubmissionState(dataItem.getDataModel(), State.SENT_VIA_SMS)
                                .andThen(Observable.just(smsSendingState));
                    }
                    return Observable.just(smsSendingState);
                });
    }

    public <T extends BaseDataModel> Completable checkConfirmationSms(final boolean searchReceived,
                                                                      final Collection<String> requiredStrings,
                                                                      final T dataModel) {

        return Single.zip(
                localDbRepository.getConfirmationSenderNumber(),
                localDbRepository.getWaitingResultTimeout(),
                Pair::create
        ).flatMapCompletable(pair ->
                smsRepository.listenToConfirmationSms(
                        searchReceived,
                        pair.second,
                        pair.first,
                        requiredStrings)
        ).andThen(
                localDbRepository.updateSubmissionState(dataModel, State.SYNCED_VIA_SMS)
        );
    }

    private Completable checkPreconditions() {
        ArrayList<Single<Boolean>> checks = new ArrayList<>();
        checks.add(deviceStateRepository.hasCheckNetworkPermission());
        checks.add(deviceStateRepository.hasReceiveSMSPermission());
        checks.add(deviceStateRepository.hasSendSMSPermission());
        checks.add(deviceStateRepository.isNetworkConnected());
        checks.add(localDbRepository.getGatewayNumber().map(number -> number.length() > 0));
        checks.add(localDbRepository.getUserName().map(username -> username.length() > 0));

        return Single.merge(checks).flatMapCompletable(checkPassed -> {
            if (!checkPassed) {
                return Completable.error(new PreconditionFailed());
            }
            return Completable.complete();
        });
    }

{'fraction_non_alphanumeric': 0.08106054209237525, 'fraction_numerical': 0.0008443806467955755, 'mean_word_length': 2.24582077281447, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6651705', 'n_tokens_mistral': 2938, 'n_tokens_neox': 2853, 'n_words': 438}