/**
 * license: GPLv3
 * reservationsystem
*/
package lodge.datamodel;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;

public class AccountList extends ArrayList<Account> {

    public static String accountSerial(String phone_number, Address mailing_address, EmailAddress email_address) {
        String serial = String.format("%09d", Math.abs(java.util.Objects.hash(phone_number, mailing_address, email_address)));
        serial = serial.length() > 8 ? serial.substring(1, 9): serial;
        return String.format("A%s",serial);
    }

    public static String reservationSerial(IReservation reservation) {
        return AccountReservationList.reservationSerial((Reservation)reservation);
    }

    // ** Add account throw error if account number is pre-existing. */
    @Override
    public synchronized boolean add(final Account account)
            throws DuplicateObjectException {
        try {
            for (Account acct : this) {
                if (acct.getAccount_number().compareTo(account.getAccount_number()) == 0) {
                    throw new DuplicateObjectException(
                            String.format("Account %s exists, duplicates not allowed.", acct.getAccount_number()));
                }
            }
        } catch (DuplicateObjectException e) {
            System.out.println(String.format("%s", e.getMessage()));
            return false;
        }
        return super.add(account);
    }

    // save accounts in edit status
    public void save(final Account acct) throws IOException {
        if (acct == null) {
            return;
        }
        Account.Write(acct);
    }

    // ** Find account return null not-existing. */
    public final Account find(String account_number) {
        for (Account acct : this) {
            if (acct.getAccount_number().compareTo(account_number) == 0) {
                return acct;
            }
        }
        return null;
    }

    public List<Account> getListOfAccounts() {
        ArrayList<Account> readList = new ArrayList<>();
        for (Account acct : this) {
            readList.add(acct);
        }
        return Collections.unmodifiableList(readList);
    }

    public List<? extends IReservation> getListOfReservations() {
        ArrayList<IReservation> readList = new ArrayList<>();
        for (Account acct : this) {
            ListIterator<IReservation> itr = acct.getAllReservations();
            while (itr.hasNext()) {
                readList.add(itr.next());
            }
        }
        return Collections.unmodifiableList(readList);
    }
}
