contract Lottery is VRFConsumerBase {
  address private _owner;
  uint256 public seed;

    
  bytes32 internal keyHash;
  uint256 internal fee;
    
  modifier requireAdmin() {
    require(_owner == msg.sender, "Requires admin privileges");      
    _;
  }

  /**
   * Constructor inherits VRFConsumerBase
   * 
   * Network: Mainnet
   * Chainlink VRF Coordinator address: 0xf0d54349aDdcf704F77AE15b96510dEA15cb7952
   * LINK token address:                0x514910771AF9Ca656af840dff83E8264EcF986CA
   * Key Hash: 0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445
   */

  constructor()
    VRFConsumerBase(
		    0xf0d54349aDdcf704F77AE15b96510dEA15cb7952, // VRF Coordinator
		    0x514910771AF9Ca656af840dff83E8264EcF986CA  // LINK Token
		    ) {

    _owner = msg.sender;
      
    keyHash = 0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445;
    fee = 2 * 10 ** 18; // 2 LINK (Varies by network)
  }

  function owner() public view virtual returns (address) {
    return _owner;
  }
    
  function getLinkBalance() public view returns (uint256) {
    return(LINK.balanceOf(address(this)));
  }

  //roll() can only be called once
  function roll() public requireAdmin {
    require(seed==0, "Already rolled"); 
    require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
    bytes32 requestId =  requestRandomness(keyHash, fee);
  }

  function fulfillRandomness(bytes32 requestId, uint256 r) internal override {
    seed = r;
  }

  function first_index_lookup(uint256 i) public view returns (uint256) {
    FirstContract first = FirstContract(0xc9Cb0FEe73f060Db66D2693D92d75c825B1afdbF);
    return first.tokenByIndex(i);
  }

  // Function returns pseudorandom sequence of numbers between 0 and 221.
  // The first 19 unique return values corresponding to registered token IDs will be winners
  function lottery_deafbeef(uint256 j) public view returns (uint256) {
    return random(j,222);
  }

  // First contract has 5000 token IDs spread out in the range between 0 and 999999
  
  // Function returns pseudorandom sequence of numbers between 0 and 4999.
  // First contract tokenByIndex() is called to map this to an actual token ID.

  //The first 2 unique return values corresponding to registered token IDs will be winners.

  function lottery_first(uint256 j) public view returns (uint256) {
    uint256 i = random(j,5000);
    return first_index_lookup(i);
  }
  
  //returns the jth entry in the pseudorandom sequence seeded by vrf
  function random(uint256 j,uint256 mod) public view returns (uint256) {
    require(seed > 0,"PRNG has not yet been seeded via Chainlink VRF");
    uint256 r = seed;
    for (uint i=0;i<j;i++) {
      unchecked {
	r = r * 16807 % 2147483647;
      }
    }
    return r % mod;
  }

}
function lottery_deafbeef(uint256 j) public view returns (uint256) {
  return random(j,222);
}

// Function returns pseudorandom sequence of numbers between 0 and 221.
// The first 19 unique return values corresponding to registered token IDs will be winners