contract AelinPoolFactory is MinimalProxyFactory {
    address public immutable AELIN_REWARDS;
    address public immutable AELIN_POOL_LOGIC;
    address public immutable AELIN_DEAL_LOGIC;

    constructor(
        address _aelinPoolLogic,
        address _aelinDealLogic,
        address _aelinRewards
    ) {
        require(_aelinPoolLogic != address(0), "cant pass null pool address");
        require(_aelinDealLogic != address(0), "cant pass null deal address");
        require(_aelinRewards != address(0), "cant pass null rewards address");
        AELIN_POOL_LOGIC = _aelinPoolLogic;
        AELIN_DEAL_LOGIC = _aelinDealLogic;
        AELIN_REWARDS = _aelinRewards;
    }

    /**
     * @dev the method a sponsor calls to create a pool
     */
    function createPool(
        string memory _name,
        string memory _symbol,
        uint256 _purchaseTokenCap,
        address _purchaseToken,
        uint256 _duration,
        uint256 _sponsorFee,
        uint256 _purchaseDuration,
        address[] memory _allowList,
        uint256[] memory _allowListAmounts
    ) external returns (address) {
        require(_purchaseToken != address(0), "cant pass null token address");
        address aelinPoolAddress = _cloneAsMinimalProxy(
            AELIN_POOL_LOGIC,
            "Could not create new deal"
        );
        AelinPool aelinPool = AelinPool(aelinPoolAddress);
        aelinPool.initialize(
            _name,
            _symbol,
            _purchaseTokenCap,
            _purchaseToken,
            _duration,
            _sponsorFee,
            msg.sender,
            _purchaseDuration,
            AELIN_DEAL_LOGIC,
            AELIN_REWARDS
        );
        if (_allowList.length > 0 || _allowListAmounts.length > 0) {
            require(
                _allowList.length == _allowListAmounts.length,
                "allowList array length issue"
            );
            aelinPool.updateAllowList(_allowList, _allowListAmounts);
        }

        emit CreatePool(
            aelinPoolAddress,
            string(abi.encodePacked("aePool-", _name)),
            string(abi.encodePacked("aeP-", _symbol)),
            _purchaseTokenCap,
            _purchaseToken,
            _duration,
            _sponsorFee,
            msg.sender,
            _purchaseDuration,
            _allowList.length > 0
        );

        return aelinPoolAddress;
    }

    event CreatePool(
        address indexed poolAddress,
        string name,
        string symbol,
        uint256 purchaseTokenCap,
        address indexed purchaseToken,
        uint256 duration,
        uint256 sponsorFee,
        address indexed sponsor,
        uint256 purchaseDuration,
        bool hasAllowList
    );
}
/**
 * @dev the factory contract allows an Aelin sponsor to permissionlessly create new pools
 */
function createPool(
    string memory _name,
    string memory _symbol,
    uint256 _purchaseTokenCap,
    address _purchaseToken,
    uint256 _duration,
    uint256 _sponsorFee,
    uint256 _purchaseDuration,
    address[] memory _allowList,
    uint256[] memory _allowListAmounts
) external returns (address) {
    require(_purchaseToken != address(0), "cant pass null token address");
    address aelinPoolAddress = _cloneAsMinimalProxy(
        AELIN_POOL_LOGIC,
        "Could not create new deal"
    );
    AelinPool aelinPool = AelinPool(aelinPoolAddress);
    aelinPool.initialize(
        _name,
        _symbol,
        _purchaseTokenCap,
        _purchaseToken,
        _duration,
        _sponsorFee,
        msg.sender,
        _purchaseDuration,
        AELIN_DEAL_LOGIC,
        AELIN_REWARDS
    );
    if (_allowList.length > 0 || _allowListAmounts.length > 0) {
        require(
            _allowList.length == _allowListAmounts.length,
            "allowList array length issue"
        );
        aelinPool.updateAllowList(_allowList, _allowListAmounts);
    }

    emit CreatePool(
        aelinPoolAddress,
        string(abi.encodePacked("aePool-", _name)),
        string(abi.encodePacked("aeP-", _symbol)),
        _purchaseTokenCap,
        _purchaseToken,
        _duration,
        _sponsorFee,
        msg.sender,
        _purchaseDuration,
        _allowList.length > 0
    );

    return aelinPoolAddress;
}

/**
 * @dev the method a sponsor calls to create a pool
 */