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

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

import lodge.reservation.IReservation;

public class AccountList extends ArrayList<Account> {

    public static String accountSerial(String phone_number, Address mailing_address, EmailAddress email_address) {
        return String.format("A%09d", Math.abs(java.util.Objects.hash(phone_number, mailing_address, email_address)));
    }

    // ** 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) {
            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<? 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);
    }

    public void showReservationList() {
        for (IReservation irsrv : this.getListOfReservations()) {
            System.out.println(String.format("Account %s: %s, %s", irsrv.getAccountNumber(),
                    irsrv.getReservation_number(), irsrv.getPhysical_address().getStreet()));
        }
    }
}
