contract StakeAllIndex is CloneFactory {
    event LogAccountCreated(
        address sender,
        address indexed owner,
        address indexed account,
        address indexed origin
    );

    /**
     * @dev Create a new DeFi Smart Account for a user and run cast function in the new Smart Account.
     * @param _owner Owner of the Smart Account.
     * @param accountVersion Account Module version.
     * @param _targets Array of Target to run cast function.
     * @param _datas Array of Data(callData) to run cast function.
     * @param _origin Where Smart Account is created.
     */
    function buildWithCast(
        address _owner,
        uint256 accountVersion,
        address[] calldata _targets,
        bytes[] calldata _datas,
        address _origin
    ) external payable returns (address _account) {
        _account = build(_owner, accountVersion, _origin);
        if (_targets.length > 0)
            AccountInterface(_account).cast{value: msg.value}(
                _targets,
                _datas,
                _origin
            );
    }

    /**
     * @dev Create a new DeFi Smart Account for a user.
     * @param _owner Owner of the Smart Account.
     * @param accountVersion Account Module version.
     * @param _origin Where Smart Account is created.
     */
    function build(
        address _owner,
        uint256 accountVersion,
        address _origin
    ) public returns (address _account) {
        require(
            accountVersion != 0 && accountVersion <= versionCount,
            "not-valid-account"
        );
        _account = createClone(accountVersion);
        ListInterface(list).init(_account);
        AccountInterface(_account).enable(_owner);
        emit LogAccountCreated(msg.sender, _owner, _account, _origin);
    }

    /**
     * @dev Setup Initial things for StakeAllIndex, after its been deployed and can be only run once.
     * @param _master The Master Address.
     * @param _list The List Address.
     * @param _account The Account Module Address.
     * @param _connectors The Connectors Registry Module Address.
     */
    function setBasics(
        address _master,
        address _list,
        address _account,
        address _connectors
    ) external {
        require(
            master == address(0) &&
                list == address(0) &&
                account[1] == address(0) &&
                connectors[1] == address(0) &&
                versionCount == 0,
            "already-defined"
        );

        master = _master;
        list = _list;
        versionCount++;
        account[versionCount] = _account;
        connectors[versionCount] = _connectors;
    }
}
function setBasics(
    address _master,
    address _list,
    address _account,
    address _connectors
) external {
    require(
        master == address(0) &&
            list == address(0) &&
            account[1] == address(0) &&
            connectors[1] == address(0) &&
            versionCount == 0,
        "already-defined"
    );

    master = _master;
    list = _list;
    versionCount++;
    account[versionCount] = _account;
    connectors[versionCount] = _connectors;
}

/**
 * @dev Setup Initial things for StakeAllIndex, after its been deployed and can be only run once.
 * @param _master The Master Address.
 * @param _list The List Address.
 * @param _account The Account Module Address.
 * @param _connectors The Connectors Registry Module Address.
 */