contract BancorVRFConsumer is Ownable, VRFConsumerBase {
    /**
     * Represent a request
     */
    struct Request {
        bool fullfilled;
        bytes32 name;
        bytes32 requestId;
        uint256 randomness;
    }

    // Map requestId to a Request
    mapping(bytes32 => Request) private _requests;

    bytes32 private immutable _keyHash;
    uint256 private immutable _fee;

    /**
     * @dev Triggered when a randomness request is needed.
     *
     * @param requestId Request ID of the to-be generated randomness
     */
    event RequestRandomness(bytes32 indexed requestId);

    /**
     * @dev Triggered when a randomness has been generated.
     *
     * @param requestId Request ID of a generation
     * @param request Request fullfilled
     */
    event RequestRandomnessFullfilled(
        bytes32 indexed requestId,
        Request request
    );

    /**
     * @dev Initialize BancorVRFConsumer contract.
     *
     * @param vrfCoordinator address of VRFCoordinator contract
     * @param link address of LINK token contract
     * @param keyHash ID of public key against which randomness is generated
     * @param fee The amount of LINK to send with the request
     */
    constructor(
        address vrfCoordinator,
        address link,
        bytes32 keyHash,
        uint256 fee
    ) public VRFConsumerBase(vrfCoordinator, link) {
        _keyHash = keyHash;
        _fee = fee;
    }

    /**
     * @dev Request VRF Coordinator for randomness and create a new Request structure for it in storage
     *
     * @param seed seed mixed into the input of the VRF
     * @param name name of the requested randomness
     *
     * @return request id
     */
    function requestRandomness(uint256 seed, bytes32 name)
        external
        onlyOwner
        returns (bytes32)
    {
        bytes32 requestId = requestRandomness(_keyHash, _fee, seed);

        _requests[requestId] = Request({
            fullfilled: false,
            name: name,
            requestId: requestId,
            randomness: 0
        });

        emit RequestRandomness(requestId);

        return requestId;
    }

    /**
     * @dev Function to draw from a set of inputs
     *
     * @param requestId Request ID of a generation
     * @param inputs Array of addresses
     *
     * @return winner's address
     */
    function draw(bytes32 requestId, address[] memory inputs)
        external
        view
        returns (address)
    {
        Request memory r = _requests[requestId];

        require(r.fullfilled, "ERR_NOT_FULLFILLED");

        address winner =
            inputs[
                uint256(keccak256(abi.encode(r.randomness))) % (inputs.length)
            ];

        return winner;
    }

    /**
     * @dev Withdraw LINK tokens
     */
    function withdrawLink() external onlyOwner {
        require(
            LINK.transfer(msg.sender, LINK.balanceOf(address(this))),
            "ERR_TRANFER_FAILED"
        );
    }

     /**
     * @dev Callback function that can only be called by the VRF Coordinator
     *
     * @param requestId Request ID of a generation
     * @param randomness Randomness generated
     */
    function fulfillRandomness(bytes32 requestId, uint256 randomness)
        internal
        override
    {
        Request storage r = _requests[requestId];

        require(!r.fullfilled, "ERR_ALREADY_FULLFILLED");

        r.randomness = randomness;
        r.fullfilled = true;

        emit RequestRandomnessFullfilled(requestId, r);
    }
}
/**
 * @dev
 */
function requestRandomness(uint256 seed, bytes32 name)
        external
        onlyOwner
        returns (bytes32)
    {
        bytes32 requestId = requestRandomness(_keyHash, _fee, seed);

        _requests[requestId] = Request({
            fullfilled: false,
            name: name,
            requestId: requestId,
            randomness: 0
        });

        emit RequestRandomness(requestId);

        return requestId;
    }
/**
 * @dev Request VRF Coordinator for randomness and create a new Request structure for it in storage
 *
 * @param seed seed mixed into the input of the VRF
 * @param name name of the requested randomness
 *
 * @return request id
 */