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

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

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

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