digraph ReservationSystemClassDiagram {
    rankdir=BT;
    splines=ortho;
    node [shape=record, style=rounded, fontname="Helvetica"];
    edge [fontname="Helvetica"];

    // --- Interfaces ---
    IReservation [label="{«interface»\nIReservation|+ ReservationType()\l+ checkValid()\l+ calculatePrice()\l+ getPricePerNight()\l...}", style=dashed];

    // --- Abstract Classes ---
    Reservation [label="{«abstract»\nReservation|- type: char\l- reservation_number: String\l- physical_address: Address\l- mailing_address: Address\l- reservation_start_date: ZonedDateTime\l- reservation_end_date: ZonedDateTime\l- reservation_status: ReservationStatusEnum\l- kitchen: KitchenTypeEnum\l- price: Float\l- accountNumber: String\l|+ Write(Reservation)\l+ Change(Reservation, ReservationStatusEnum)\l+ ReservationType()\l...}"];

    // --- Concrete Classes ---
    TestReservations [label="{TestReservations|+ main(String[])\l- Test_AddAccount(...)\l- Test_AddReservation(...)\l}"];
    AccomodationManager [label="{AccomodationManager|- accounts: AccountList\l|+ loadAll()\l+ retrieveAccount(String)\l+ AddAccount(Account)\l+ UpdateAccount(Account)\l+ newAccount(...)\l+ addReservation(Account, Reservation)\l...}"];
    DataRepository [label="{DataRepository|- directoryPath: String\l- instance: DataRepository\l+ getInstance()\l+ WalkFileSystemTree(...)\l+ LoadAccount(Path)\l+ Reservation(String)\l...}"];
    Account [label="{Account|- account_number: String\l- phone_number: String\l- mailing_address: Address\l- email_address: EmailAddress\l- reservations: AccountReservationList\l|+ add(Reservation)\l+ Write(Account)\l+ findReservation(String)\l...}"];
    AccountList [label="{AccountList|+ add(Account)\l+ find(String)\l+ save(Account)\l...}"];
    AccountReservationList [label="{AccountReservationList|+ add(IReservation)\l+ find(String)\l...}"];
    HotelReservation [label="{HotelReservation|+ ReservationType()\l+ checkValid()\l+ calculatePrice()\l...}"];
    CabinReservation [label="{CabinReservation|+ ReservationType()\l+ checkValid()\l+ calculatePrice()\l...}"];
    HouseReservation [label="{HouseReservation|+ ReservationType()\l+ checkValid()\l+ calculatePrice()\l...}"];
    Address [label="{Address|- street: String\l- city: String\l- state: String\l- zip: String\l}"];
    EmailAddress [label="{EmailAddress|- email: String\l}"];

    // --- Enums ---
    ReservationStatusEnum [label="{«enumeration»\nReservationStatusEnum|Draft\lCompleted\lCanceled\l}", style=filled, fillcolor=lightgrey];
    KitchenTypeEnum [label="{«enumeration»\nKitchenTypeEnum|None\lKitchenette\lFullKitchen\l}", style=filled, fillcolor=lightgrey];

    // --- Inheritance & Implementation ---
    edge [arrowhead=empty, style=solid];
    HotelReservation -> Reservation;
    CabinReservation -> Reservation;
    HouseReservation -> Reservation;
    
    edge [arrowhead=empty, style=dashed];
    Reservation -> IReservation;

    // --- Aggregation & Composition ---
    edge [arrowhead=diamond, style=solid, label="1"];
    AccomodationManager -> AccountList [label="1..*", headlabel="manages"];
    Account -> AccountReservationList [label="1..*", headlabel="has"];
    Account -> Address [label="1", headlabel="mailing"];
    Account -> EmailAddress [label="1"];
    Reservation -> Address [label="0..2", headlabel="physical/mailing"];
    Reservation -> ReservationStatusEnum [label="1"];
    Reservation -> KitchenTypeEnum [label="1"];
    AccountReservationList -> IReservation [arrowhead=odiamond, label="0..*"];
    AccountList -> Account [arrowhead=odiamond, label="0..*"];


    // --- Dependencies ---
    edge [arrowhead=vee, style=dashed, label="«uses»"];
    TestReservations -> AccomodationManager;
    TestReservations -> HotelReservation;
    TestReservations -> CabinReservation;
    TestReservations -> HouseReservation;
    AccomodationManager -> DataRepository;

    DataRepository -> AccomodationManager;
    DataRepository -> Account;
    DataRepository -> Reservation;
    Account -> DataRepository;
    Reservation -> DataRepository;
}
