/*
 * File: src/main/java/reports/config/PurchaseDbConfig.java
 * Description: This configuration class sets up the data source, entity manager,
 * and transaction manager for the purchase database in the ERP application.
 * It uses HikariCP as the connection pool and configures JPA repositories
 * for managing purchase-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.purchase) and associates them with the
 *   purchase entity manager and transaction manager.
 *
 * - **DataSource**: A bean method (`purchaseDataSource`) initializes a HikariDataSource
 *   with properties prefixed with "spring.database.purchase", allowing configuration
 *   through application properties.
 *
 * - **LocalContainerEntityManagerFactoryBean**: The `purchaseEntityManager` method
 *   configures the entity manager for purchase-related entities, setting the data source
 *   and specifying the package where entity classes are located (com.nebula.erp.reports.model.purchase).
 *
 * - **PlatformTransactionManager**: The `purchaseTransactionManager` method creates a
 *   JPA transaction manager using the purchase entity manager, enabling transaction
 *   management for purchase-related database operations.
 *
 * This configuration is essential for ensuring that all purchase-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.purchase",  // Package to scan for JPA repositories
        entityManagerFactoryRef = "purchaseEntityManager",   // Reference to the entity manager factory bean
        transactionManagerRef = "purchaseTransactionManager"  // Reference to the transaction manager bean
)
public class PurchaseDbConfig {

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

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

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