package com.airlock.iam.admin.infrastructure.service;

import com.airlock.iam.base.api.domain.model.exception.ViolationException;
import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.common.domain.model.logs.Log;
import com.airlock.iam.common.domain.model.usertrail.UserTrailLogRepository;
import com.airlock.iam.common.domain.service.logs.UserTrailLogParserHelper;
import com.airlock.iam.log.usertrail.UserTrailLog;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.List;

public final class UserTrailLogsRestResponseService {
   private static final int LIMIT_MIN = 1;
   private static final int LIMIT_MAX = 500;
   private final Provider<UserTrailLogRepository> logRepository;

   @Inject
   UserTrailLogsRestResponseService(Provider<UserTrailLogRepository> logRepository) {
      this.logRepository = logRepository;
   }

   public LogsSearchResult getLogs(UserId userId, int limit, int offset) {
      assertLimitWithinAllowedRange(limit);
      assertOffsetWithinAllowedRange(offset);
      List<UserTrailLog> userTrailLogs = ((UserTrailLogRepository)this.logRepository.get()).findBy(userId, limit + 1, offset);
      return new LogsSearchResult(userTrailLogs.stream().<Log>map(UserTrailLogParserHelper::mapToLog).limit(limit).toList(), userTrailLogs.size() > limit);
   }

   private static void assertLimitWithinAllowedRange(int limit) {
      if (limit < 1 || limit > 500) {
         throw new ViolationException(String.format("Log limit %d is not within range from %d to %d (inclusive).", limit, 1, 500));
      }
   }

   private static void assertOffsetWithinAllowedRange(int offset) {
      if (offset < 0) {
         throw new ViolationException("Offset must be non-negative.");
      }
   }
}
