package at.procon.eventhub.esperpoc.service;

import at.procon.eventhub.esperpoc.dto.ActivityIntervalDto;
import java.time.Duration;
import java.time.LocalDate;
import java.util.Objects;
import java.util.Set;

final class EsperActivitySemantics {

    private static final Set<String> ACTIVE_ACTIVITY_TYPES = Set.of("DRIVE", "WORK", "AVAILABILITY");

    private EsperActivitySemantics() {
    }

    static boolean canMerge(ActivityIntervalDto left, ActivityIntervalDto right, Duration tolerance) {
        boolean sameDriver = Objects.equals(left.driverEntityId(), right.driverEntityId());
        boolean sameActivity = Objects.equals(left.activityType(), right.activityType());
        boolean sameSlot = Objects.equals(left.cardSlot(), right.cardSlot());
        boolean sameCardStatus = Objects.equals(left.cardStatus(), right.cardStatus());
        boolean sameDrivingStatus = Objects.equals(left.drivingStatus(), right.drivingStatus());
        boolean sameSourceKind = Objects.equals(left.sourceKind(), right.sourceKind());
        long gapSeconds = Duration.between(left.endedAt(), right.startedAt()).getSeconds();
        boolean adjacentOrOverlapping = gapSeconds <= tolerance.getSeconds();
        return sameDriver && sameActivity && sameSlot && sameCardStatus && sameDrivingStatus && sameSourceKind && adjacentOrOverlapping;
    }

    static boolean isShiftActivity(ActivityIntervalDto interval) {
        return isKnownActivity(interval) && ACTIVE_ACTIVITY_TYPES.contains(interval.activityType());
    }

    static boolean isRestOrUnknown(ActivityIntervalDto interval) {
        return ("BREAK_REST".equals(interval.activityType()) && isKnownActivity(interval))
                || isUnknownActivity(interval);
    }

    static boolean isKnownActivity(ActivityIntervalDto interval) {
        return interval.cardStatus() == null
                || !"NOT_INSERTED".equals(interval.cardStatus())
                || "KNOWN".equals(interval.drivingStatus());
    }

    static boolean isUnknownActivity(ActivityIntervalDto interval) {
        if ("UNKNOWN_ACTIVITY".equals(interval.activityType())) {
            return true;
        }
        return "UNKNOWN".equals(interval.drivingStatus())
                || ("NOT_INSERTED".equals(interval.cardStatus()) && !"KNOWN".equals(interval.drivingStatus()));
    }

    static LocalDate recordDate(ActivityIntervalDto interval) {
        return interval.startedAt().toLocalDate();
    }
}
