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

import java.util.ArrayList;

import lodge.reservation.IReservation;
import lodge.reservation.Reservation;

class AccountReservationList extends ArrayList<IReservation> {

    private static String reservationSerial(Reservation reservation) {
        return String.format("R%010d", Math.abs(java.util.Objects.hash(reservation.getPhysical_address())));
    }

    @Override
    public synchronized boolean add(final IReservation reservation) throws RuntimeException {
        boolean result = true;
        Reservation rsrv = this.find(reservation.getReservation_number());
        result = rsrv == null;
        if (!result) {
            throw new DuplicateObjectException(
                    String.format("Error No Dups, Reservation exists: %s.", rsrv.getReservation_number()));
        }
        result = ((IReservation) reservation).checkValid();

        if (result) {
            ((Reservation) reservation)
                    .setReservation_number(AccountReservationList.reservationSerial((Reservation) reservation));
            ((Reservation) reservation).setPrice(reservation.calculatePrice());
            result = super.add(reservation);
        } else {
            throw new IllegalArgumentException(String.format("error reservation invalid: %s",
                    ((Reservation) reservation).getReservation_number()));
        }
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("\"reservations\":[");

        for (int ix = 0; ix < this.size(); ix++) {
            String name = this.get(ix).ReservationType() + "";

            if ((this.size() - 1) == ix) {
                sb.append(String.format("{\"%s\":{\"reservation_number\":\"%s\"}}", name,
                        this.get(ix).getReservation_number()));
            } else {
                sb.append(String.format("{\"%s\":{\"reservation_number\":\"%s\"}},", name,
                        this.get(ix).getReservation_number()));
            }
        }
        sb.append("]");
        return sb.toString();
    }

    public Reservation find(String reservation_number) {
        for (IReservation rsrv : this) {
            if (rsrv.getReservation_number().compareTo(reservation_number) == 0) {
                return (Reservation) rsrv;
            }
        }
        return null;
    }

    public void update(AccountReservationList incoming_reservation_list) {
        for (IReservation rsrv : incoming_reservation_list) {
            Reservation onListRsrv = find(rsrv.getReservation_number());
            if (onListRsrv != null) {
                onListRsrv.update((Reservation) rsrv);
            }
        }
    }
}
