the_big_one/src/main/java/jesse/keeblarcraft/BankMgr/IndividualBank.java

164 lines
8.0 KiB
Java
Raw Normal View History

package jesse.keeblarcraft.BankMgr;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import static java.util.Map.entry;
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
// Contains the information of an individual bank
//
// The bank will keep track of all accounts within its facilities. In addition to accounts, the bank
// maintains its own identifier which is unique and other misc things.
public class IndividualBank {
private Map<String, Integer> ACCOUNT_TYPES = Map.ofEntries(
entry("checking", 0),
entry("savings", 1)
);
ConfigManager config = new ConfigManager();
private Integer routingNumber; // this is the banks unique identifier
private Integer numberOfAccounts; // Total number of accounts the bank has. This includes only active accounts inside accountsList.
private String bankFourLetterIdentifier;
private Integer maxBankAccounts = 100_000_000; // Making this simple for myself any one type of account has 8 random numbers genereated so 10^8 possible accounts
// Think FDIC but from the servers account (keeblarcraft insurance corporation)
// KBIC will ensure an amount of money based on its trustworthiness to a bank and the number of holders it has.
private Integer kbicInsuredAmount;
private Boolean kbicInsured;
// bankMoney is the total amount of money the bank possesses itself. The bank itself is personally responsible
// for backing the amount of money it claims it has and this is the balance that is withdrawn from for credits.
// A bank can have a sum of money that is less than the total amount of money of all its account holders
private Integer bankMoney;
// Key = ACCOUNT NUMBER
// Value = ACCOUNT
private HashMap<Integer, IndividualAccount> accountsList;
private HashMap<String, List<Integer>> accountsListFromName; // This is a list that just points to a list of account numbers by person. USEFUL
private List<String> lockedUsers; // A list of users who are locked out of the bank and are incapable of performing more actions within it
public IndividualBank(String routingNumber) {
accountsList = new HashMap<Integer, IndividualAccount>();
accountsListFromName = new HashMap<String, List<Integer>>();
// READ IN BANK CONFIG
// A modified config reader is needed here for when each IndividualAccount is read in - the name is taken from that and is attached to the
// 'accountsListFromName' structure. This makes it no worse than O(n) to fill these two structures in.
// NOTE: This is an *EXPENSIVE* operation! Future us might need to update this. Also note a method is needed for everytime a player opens a new account
// or gets put on one to update the map every time
for (Entry<Integer, IndividualAccount> account : accountsList.entrySet()) {
// We must loop over the string of holders for each account as well to make the flattened accountsListFromName map
List<String> accountHolders = account.getValue().GetAccountHolders();
// Match each user to the secondary map & add to list-value if not existing
for (Integer holderIndex = 0; holderIndex < accountHolders.size(); holderIndex++) {
if (accountsListFromName.containsKey(accountHolders.get(holderIndex))) {
// Case 1: User exists, update map entry
accountsListFromName.get(accountHolders.get(holderIndex)).add(account.getKey()); // Add a new account id to this person in the new flat map
} else {
// Case 2: User does not already exist; add a new map entry
accountsListFromName.put(accountHolders.get(holderIndex), List.of(account.getKey())); // Store name as key, and new List with the value of ACCOUNT #
}
}
}
numberOfAccounts = accountsList.size();
}
// Updates the regular bank account list & the fast-access bank account list
// NO values are allowed to be null. Manually update lists separately if that's the behaviour you want!
public void UpdateBankAccounts(String newHolderName, Integer accountIdentifier, IndividualAccount newAccountOnly) {
// Update the fast-access map first
if (accountsListFromName.containsKey(newHolderName)) {
// Check if user is already in map
accountsListFromName.get(newHolderName).add(accountIdentifier);
} else {
// Add new entry to map
accountsListFromName.put(newHolderName, List.of(accountIdentifier));
}
// Update regular account list
if (accountsList.containsKey(accountIdentifier)) {
// This path assumes we are adding a holder as opposed to adding an account (else, how else would this work?)
accountsList.get(accountIdentifier).AddAccountHolder(newHolderName);
} else {
// Non-existent account means a new one!
accountsList.put(accountIdentifier, newAccountOnly);
numberOfAccounts++;
}
}
public Boolean CreateAccount(String holderName, String accountTypeStr) {
Boolean success = false;
if (accountsList.size() <= maxBankAccounts && ACCOUNT_TYPES.containsKey(accountTypeStr.toLowerCase())) {
// Verify this isn't a blacklisted user
if (!lockedUsers.contains(holderName)) {
Integer maxAttempts = 1000; // Reasonably a unique bank account should pop up within 1000 generations. If not, the user may try again.
String accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountTypeStr), holderName);
// TODO: Fix in future with a method that will guarentee a one-time necessary number generator. Statistically speaking; this will be okay for the
// entire life time of the server. BUT, you never know!
while (maxAttempts != 0 && !accountsList.containsKey(AccountNumberGenerator.GetAccountNumberFromId(accountId))) {
accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountTypeStr), holderName);
maxAttempts--;
}
// Final check to add the account
Integer actualAccountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
if (!accountsList.containsKey(actualAccountNumber)) {
IndividualAccount newAccount = new IndividualAccount(actualAccountNumber, this.routingNumber, List.of(holderName), false, 0, "");
UpdateBankAccounts(holderName, actualAccountNumber, newAccount);
success = true;
}
}
}
return success;
}
public void AliasAccount(String accountId, String newAlias) {
Integer accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
if (accountsList.containsKey(accountNumber)) {
accountsList.get(accountNumber).AliasAccount(newAlias);
}
}
public Boolean LockAccountHolder(String holderName) {
Boolean success = false;
Integer accountIter = 0;
for (Entry<String, List<Integer>> holderAccounts : accountsListFromName.entrySet()) {
accountsList.get(holderAccounts.getValue().get(accountIter++)).LockAccount();
}
return success;
}
public Boolean CloseAccount(String accountId) {
Boolean success = false;
Integer accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
if (accountsList.get(accountNumber).GetAccountBalance() == 0) {
accountsList.remove(accountNumber);
success = true;
}
return success;
}
public Boolean HasAccount(Integer accountIdentifier) {
Boolean containsAccount = false;
if (accountsList.containsKey(accountIdentifier)) {
containsAccount = true;
}
return containsAccount;
}
}