//Generate an sophia smartcontract for the aeternity bblockchain that satisfies the given bdd 
//
//Given I have an ae wallet SubAccount with 0 ae
//And I have an ae wallet Fund with 100 ae
//And I have an bitcoin wallet with 0.00070883 btc
//And the AE/BTC exchange rate is 0.0003
//When I call the spend function with integer argument "Unit"
//Then then "Unit" aettos must be transfered from wallet Fund to SubAccount
//Then the unit value must be accumulated with every spend
//When I call the publish function with binary argument "BDDHash"
//Then the "BDDHash" must be stored
//
contract AeForUsers =
    record state = {
        receiver: map(address, int),
        deployer: address,
		owner: string,
		feature_hash: string,
		fee: int,
        mbtc_balance: int, // sum of balance of every register user
        total_balance: int // sum of balance of every register user
      }
    stateful entrypoint init(owner: string, feature_hash: string, fee: int) = {
        receiver = {},
		owner = owner,
        deployer = Call.caller,
        mbtc_balance = 0 ,
		feature_hash = feature_hash,
		fee= fee,
        total_balance = 0 
      }

    // Let user send money to this contract
    payable stateful entrypoint send_money_to_this_contract() : bool =
       true

    // Set receiver with the maximum amount it can withdraw
    stateful entrypoint set_receiver(raddress: address, can_withdraw: int) =
       require(Call.caller == state.deployer, "Only owner can set receiver") 
       // Check if contract balance exsists before adding it for user.
       if(Contract.balance >= can_withdraw)
         put(state{total_balance = state.total_balance + can_withdraw})

       if(Contract.balance >= state.total_balance)
         put(state{receiver[raddress] = can_withdraw})
        
       // If total balance of all users is bigger than balance available in this contract
       // then we can't add user and need to decreased total (which increased above)
       else
         put(state{total_balance = state.total_balance - can_withdraw})
    
    
    // Let user withdraw the amount they want to and subtract that from the amount they can withdraw
    stateful entrypoint withdraw(amount_to_withdraw: int) =
        if(state.receiver[Call.caller] >= amount_to_withdraw)
          put(state{receiver[Call.caller] = state.receiver[Call.caller] - amount_to_withdraw})
          put(state{mbtc_balance = state.mbtc_balance - amount_to_withdraw})
          put(state{total_balance = state.total_balance - amount_to_withdraw})
          Chain.spend(Call.caller, amount_to_withdraw)

    // Check User(Caller) Balance
    stateful entrypoint checkUserBalance(): int =
      state.receiver[Call.caller]
    
    // Check the total balance available in contract
    stateful entrypoint checkContractBalance(): int =
      Contract.balance
    
    stateful entrypoint getSumOfTotalBalanceOfUser(): int =
      state.total_balance

    // Withdraw leftovers
    stateful entrypoint withdrawAll() =
      if(Call.caller == state.deployer)
        Chain.spend(Call.caller, Contract.balance-state.total_balance)

