package com.eactive.eai.manage.inflow;

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

import org.springframework.stereotype.Service;

import com.eactive.eai.common.inflow.Bucket;
import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.inflow.InflowGroupVO;
import com.eactive.eai.common.inflow.dual.DualInflowControlManager;

@Service
public class InflowGroupMetricService {

    public GroupMetricDTO getGroupMetric(String groupId) {
        DualInflowControlManager manager = getManager();
        if (manager == null) return null;

        InflowGroupVO groupVo = manager.getGroupInflowThreshold(groupId);
        if (groupVo == null) return null;

        return buildDTO(groupId, groupVo, manager.getGroupMetrics(groupId));
    }

    public List<GroupMetricDTO> getAllGroupMetrics() {
        DualInflowControlManager manager = getManager();
        if (manager == null) return new ArrayList<>();

        List<GroupMetricDTO> result = new ArrayList<>();
        for (String groupId : manager.getGroupAllKeys()) {
            GroupMetricDTO dto = getGroupMetric(groupId);
            if (dto != null) result.add(dto);
        }
        return result;
    }

    public boolean resetGroupMetric(String groupId) {
        DualInflowControlManager manager = getManager();
        if (manager == null) return false;
        if (manager.getGroupInflowThreshold(groupId) == null) return false;
        manager.resetGroupMetrics(groupId);
        return true;
    }

    public void resetAllGroupMetrics() {
        DualInflowControlManager manager = getManager();
        if (manager != null) manager.resetAllGroupMetrics();
    }

    protected DualInflowControlManager getManager() {
        Bucket bucket = InflowControlUtil.getBucket();
        return (bucket instanceof DualInflowControlManager)
            ? (DualInflowControlManager) bucket
            : null;
    }

    private GroupMetricDTO buildDTO(String groupId, InflowGroupVO groupVo,
                                    DualInflowControlManager.TargetMetrics m) {
        GroupMetricDTO dto = new GroupMetricDTO();
        dto.setGroupId(groupId);
        dto.setGroupName(groupVo.getGroupName());
        dto.setActivate(groupVo.isActivate());

        if (m != null) {
            long allowed = m.allowed.get();
            long rejPs   = m.rejectedPerSecond.get();
            long rejTh   = m.rejectedThreshold.get();
            long total   = allowed + rejPs + rejTh;
            dto.setAllowed(allowed);
            dto.setRejectedPerSecond(rejPs);
            dto.setRejectedThreshold(rejTh);
            dto.setTotalRequests(total);
            dto.setRejectRatio(total > 0
                ? Math.round((double)(rejPs + rejTh) / total * 10000) / 100.0
                : 0.0);
            dto.setLastResetTime(m.lastResetTime);
        }
        return dto;
    }
}
