/*
 * File: src/main/java/reports/config/InventoryDbConfig.java
 * Description: This configuration class sets up the data source, entity manager,
 * and transaction manager for the inventory database in the ERP application.
 * It uses HikariCP as the connection pool and configures JPA repositories
 * for managing inventory-related entities.
 *
 * Key Components:
 *
 * - **@Configuration**: Indicates that this class contains Spring configuration.
 *
 * - **@EnableJpaRepositories**: Enables JPA repositories in the specified package
 *   (com.nebula.erp.reports.repository.inventories) and associates them with the
 *   inventory entity manager and transaction manager.
 *
 * - **DataSource**: A bean method (`inventoryDataSource`) initializes a HikariDataSource
 *   with properties prefixed with "spring.database.inventory", allowing configuration
 *   through application properties.
 *
 * - **LocalContainerEntityManagerFactoryBean**: The `inventoryEntityManager` method
 *   configures the entity manager for inventory-related entities, setting the data source
 *   and specifying the package where entity classes are located (com.nebula.erp.reports.model.inventories).
 *
 * - **PlatformTransactionManager**: The `inventoryTransactionManager` method creates a
 *   JPA transaction manager using the inventory entity manager, enabling transaction
 *   management for inventory-related database operations.
 *
 * This configuration is essential for ensuring that all inventory-related
 * database operations are handled through the specified data source and
 * transaction manager, maintaining separation from other database contexts in the application.
*/

package com.nebula.erp.reports.config;

import org.springframework.beans.factory.annotation.Qualifier;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
@EnableJpaRepositories(
        basePackages = "com.nebula.erp.reports.repository.inventories",  // Package to scan for JPA repositories
        entityManagerFactoryRef = "inventoryEntityManager",  // Reference to the entity manager factory bean
        transactionManagerRef = "inventoryTransactionManager"  // Reference to the transaction manager bean
)
public class InventoryDbConfig {

    /*
     * Component: DataSource
     * This method initializes a HikariDataSource for managing connections to the inventory database.
     */
    @Bean(name = "inventoryDataSource") // Defines a bean named 'inventoryDataSource'
    @ConfigurationProperties(prefix = "spring.database.inventory")
    public DataSource inventoryDataSource() {
        return new HikariDataSource();
    }

    /*
     * Component: Entity Manager
     * This method configures the entity manager for inventory entities, linking it with the data source.
     */
    @Bean(name = "inventoryEntityManager") // Defines a bean named 'inventoryEntityManager'
    public LocalContainerEntityManagerFactoryBean inventoryEntityManager(
            @Qualifier("inventoryDataSource") DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan("com.nebula.erp.reports.model.inventories");
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        return em;
    }

    /*
     * Component: Transaction Manager
     * This method creates a transaction manager for managing transactions associated with inventory operations.
     */
    @Bean(name = "inventoryTransactionManager") // Defines a bean named 'inventoryTransactionManager'
    public PlatformTransactionManager inventoryTransactionManager(
            @Qualifier("inventoryEntityManager") LocalContainerEntityManagerFactoryBean inventoryEntityManager) {
        return new JpaTransactionManager(inventoryEntityManager.getObject());
    }
}
