package cz.senslog.connector.fetch.azure;

import cz.senslog.connector.model.api.ProxySessionModel;

import java.time.OffsetDateTime;
import java.util.*;

import static java.time.OffsetDateTime.MIN;

class AzureSession extends ProxySessionModel {

    static class UnitSession {
        boolean used;

        OffsetDateTime lastTime;

        public UnitSession(OffsetDateTime lastTime) {
            this.used = false;
            this.lastTime = lastTime;
        }
    }

    private Map<String, UnitSession> unitSessions;

    public static AzureSession emptySession() {
        return new AzureSession(false);
    }

    public AzureSession(boolean isActive) {
        super(isActive);
        this.unitSessions = new HashMap<>();
    }

    public void addLastUnitTime(String unitId, OffsetDateTime unitTime) {
        String id = unitId.toUpperCase();
        UnitSession unitSession = unitSessions.get(id);
        if (unitSession == null) {
            unitSession = new UnitSession(unitTime);
            unitSessions.put(id, unitSession);
        } else if (unitTime.isAfter(unitSession.lastTime)) {
            unitSession.lastTime = unitTime;
        }
    }

    public OffsetDateTime getLastTimeForUnit(String unitId, OffsetDateTime minUnitTime) {
        OffsetDateTime savedLast = getLastTimeForUnit(unitId);
        savedLast = savedLast == null ? MIN : savedLast;
        return savedLast.isBefore(minUnitTime) ? minUnitTime : savedLast;
    }

    public OffsetDateTime getLastTimeForUnit(String unitId) {
        String id = unitId.toUpperCase();
        UnitSession unitSession = this.unitSessions.get(id);
        if (unitSession != null) {
            unitSession.used = true;
            return unitSession.lastTime;
        }

        return null;
    }

    public String[] reduceLastUnits(String... validUnits) {
        Set<String> unitsSet = new HashSet<>(Arrays.asList(validUnits));
        List<String> removed = new ArrayList<>();
        Iterator<Map.Entry<String, UnitSession>> unitIterator = unitSessions.entrySet().iterator();
        while (unitIterator.hasNext()) {
            Map.Entry<String, UnitSession> entry = unitIterator.next();
            if (unitsSet.contains(entry.getKey())) {
                removed.add(entry.getKey());
                unitIterator.remove();
            }
        }
        return removed.toArray(new String[0]);
    }

    @Override
    public String toString() {
        boolean isEmpty = !isActive() && unitSessions.isEmpty();
        return "AzureSession." + (isEmpty ? "empty" : "active");
    }
}
