Newer
Older
Dinner / Program.cs
@Derek Comartin Derek Comartin on 22 Aug 2023 2 KB Init
namespace Dinner;

class Dinner
{
    private readonly uint _availableSeats;
    private readonly DateTime _scheduled;
    private readonly List<Reservation> _reservations;
    private readonly List<IEvent> _events = new();
    private readonly Guid _dinnerId;

    private Dinner(Guid dinnerId, uint availableSeats, DateTime scheduled)
    {
        _dinnerId = dinnerId; 
        _availableSeats = availableSeats;
        _scheduled = scheduled;
        _reservations = new List<Reservation>();
        
        _events.Add(new DinnerPlanned(_dinnerId));
    }
    
    public static Dinner PlanDinner(Guid dinnerId, uint availableSeats, DateTime scheduled)
    {
        if (availableSeats == 0)
        {
            throw new InvalidOperationException("Must have at least one seat at a dinner.");
        }
        
        return new Dinner(dinnerId, availableSeats, scheduled);
    }

    public bool ReserveSeat(Guest guest)
    {
        if (_reservations.Count <= _availableSeats)
        {
            _reservations.Add(new Reservation(Guid.NewGuid(), guest));
            _events.Add(new DinnerSeatReserved(_dinnerId, guest.GuestId));
            
            return true;
        }

        return false;
    }

    public void CancelReservation(Guest guest)
    {
        var reservation = _reservations.SingleOrDefault(x => x.Guest.Equals(guest));
        if (reservation == null)
        {
            throw new InvalidOperationException("Guest does not have a reservation.");
        }

        _reservations.Remove(reservation);
    }

    public void ConfirmReservation(Guest guest)
    {
        var reservation = _reservations.SingleOrDefault(x => x.Guest.Equals(guest));
        if (reservation == null)
        {
            throw new InvalidOperationException("Guest does not have a reservation.");
        }

        reservation.Confirm();
    }

    public void StartDinner()
    {
        var confirmedReservations = _reservations.Where(x => x.IsConfirmed);
        _events.Add(new DinnerHosted(_dinnerId, confirmedReservations));
    }
}

record Reservation(Guid ReservationId, Guest Guest)
{
    public bool IsConfirmed { get; private set; }
    
    public void Confirm()
    {
        IsConfirmed = true;
    }
}

record Guest(Guid GuestId, string Name);