package com.eactive.eai.common.inflow;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.jdbc.Sql;

import com.eactive.eai.common.lifecycle.LifecycleException;
import com.eactive.eai.data.CommonJPATestConfiguration;
import com.eactive.eai.data.jpa.BaseRepositoryImpl;

@DataJpaTest
@ContextConfiguration(classes = { CommonJPATestConfiguration.class })
@ComponentScan({ "com.eactive.eai.common.inflow" })
@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = {
		"com.eactive.eai.common.inflow" })
@EntityScan({ "com.eactive.eai.data.entity.onl.inflow" })
@Sql({
	"/com/eactive/eai/common/inflow/init_tseaifr09.sql",
	"/com/eactive/eai/common/inflow/init_tseaifr11.sql",
	"/com/eactive/eai/common/inflow/init_inflow_control_group.sql",
	"/com/eactive/eai/common/inflow/init_inflow_control_group_mapping.sql"
})
class InflowControlManagerTest {

	@Autowired
	InflowControlManager inflowControlManager;

	@BeforeEach
	void setUp() throws Exception {
		if (!inflowControlManager.isStarted()) {
			inflowControlManager.start();
		} else {
			inflowControlManager.reloadAdapter();
			inflowControlManager.reloadInterface();
			inflowControlManager.reloadGroup();
		}
	}

	@Test
	void testStart() {
		assertTrue(inflowControlManager.isStarted());
	}

	@Test
	void testGetGroupBucket_existingGroup_returnsNotNull() {
		assertNotNull(inflowControlManager.getGroupBucket("test-group-001"));
	}

	@Test
	void testGetGroupBucket_unknownGroup_returnsNull() {
		assertNull(inflowControlManager.getGroupBucket("non-existent-group"));
	}

	@Test
	void adapter_spikePasses_thenBurstBlocked() {
		for (int i = 0; i < 5; i++) assertTrue(inflowControlManager.isAdapterPass("TEST_ADAPTER"));
		assertFalse(inflowControlManager.isAdapterPass("TEST_ADAPTER"));
	}

	@Test
	void interface_spikePasses_thenBurstBlocked() {
		for (int i = 0; i < 5; i++) assertTrue(inflowControlManager.isInterfacePass("TEST_INTERFACE"));
		assertFalse(inflowControlManager.isInterfacePass("TEST_INTERFACE"));
	}

	@Test
	void group_spikePasses_thenBurstBlocked() {
		for (int i = 0; i < 5; i++) assertNull(inflowControlManager.isGroupPass("test-group-quota"));
		assertEquals(CustomGroupBucket.RESULT_BLOCKED_THRESHOLD, inflowControlManager.isGroupPass("test-group-quota"));
	}

}
