package com.airlock.iam.common.infrastructure.sso;

import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import java.time.Instant;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

class AcceptedSsoTickets {
   private static final ELogger LOG = ELoggerFactory.getLogger(AcceptedSsoTickets.class);
   private static final int MAX_REMEMBERED_TICKETS = 100000;
   private final Map<String, Long> tickets = createLimitedSizeMap();

   synchronized boolean containsAcceptedTicket(String ssoTicketId) {
      return this.tickets.containsKey(ssoTicketId);
   }

   synchronized void storeAcceptedTicket(String ssoTicketId, Instant expirationDate) {
      this.tickets.put(ssoTicketId, expirationDate.toEpochMilli());
   }

   synchronized void cleanup() {
      Set<String> toBeRemoved = new HashSet<>();
      long now = System.currentTimeMillis();

      for (Entry<String, Long> entry : this.tickets.entrySet()) {
         long expDate = entry.getValue();
         if (expDate <= now) {
            toBeRemoved.add(entry.getKey());
         }
      }

      for (String t : toBeRemoved) {
         this.tickets.remove(t);
      }

      if (!toBeRemoved.isEmpty()) {
         LOG.debug(String.format("Removed %s expired SSO tickets from accepted SSO tickets in memory repository", toBeRemoved.size()));
      }
   }

   private static Map<String, Long> createLimitedSizeMap() {
      return new LinkedHashMap<String, Long>(1013) {
         @Override
         protected boolean removeEldestEntry(Entry<String, Long> e) {
            return this.size() > 100000;
         }
      };
   }
}
