-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathparking_lot.go
More file actions
107 lines (85 loc) · 2.42 KB
/
Copy pathparking_lot.go
File metadata and controls
107 lines (85 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main
import (
"fmt"
"lld_go_parking_lot/vehicles"
"sync"
"time"
)
var (
parkingLotInstance *ParkingLot
once sync.Once
)
type ParkingLot struct {
Name string
floors []*ParkingFloor
tickets map[string]*ParkingTicket
}
func GetParkingLotInstance() *ParkingLot {
once.Do(func() {
parkingLotInstance = &ParkingLot{
tickets: make(map[string]*ParkingTicket),
}
})
return parkingLotInstance
}
func (pl *ParkingLot) AddFloor(floorID int) {
pl.floors = append(pl.floors, NewParkingFloor(floorID))
}
func (pl *ParkingLot) DisplayAvailability() {
fmt.Printf("Parking Lot: %s\n", pl.Name)
for _, floor := range pl.floors {
floor.DisplayFloorStatus()
}
}
func (pl *ParkingLot) findParkingSpot(vehicleType vehicles.VehicleType) (*ParkingSpot, error) {
for _, floor := range pl.floors {
if spot := floor.FindParkingSpot(vehicleType); spot != nil {
return spot, nil
}
}
return nil, fmt.Errorf("no available parking spot found for %s", vehicleType)
}
func (pl *ParkingLot) ParkVehicle(vehicle vehicles.VehicleInterface) (*ParkingTicket, error) {
parkingSpot, err := pl.findParkingSpot(vehicle.GetVehicleType())
if err != nil {
return nil, err
}
err = parkingSpot.ParkVehicle(vehicle)
if err != nil {
return nil, err
}
parkingTicket := NewParkingTicket(vehicle, parkingSpot)
pl.tickets[parkingTicket.TicketId] = parkingTicket
fmt.Printf("%s parked successfully. Ticket: %v\n",
vehicle.GetLicenceNumber(),
parkingTicket,
)
return parkingTicket, nil
}
func (p *ParkingLot) UnparkVehicle(parkingTicketID string) error {
if len(parkingTicketID) == 0 {
return fmt.Errorf("invalid parking ticket id")
}
parkingTicket := p.tickets[parkingTicketID]
if parkingTicket == nil {
return fmt.Errorf("invalid parking ticket")
}
if parkingTicket.Status == Closed {
return fmt.Errorf("ticket is already used for exit")
}
parkingTicket.SetExitTime(time.Now())
charge, err := parkingTicket.CalculateTotalCharge()
if err != nil {
return err
}
formattedCharge := fmt.Sprintf("%.2f", charge)
fmt.Printf("bill for %s = %s\n", parkingTicket.Vehicle.GetLicenceNumber(), formattedCharge)
paymentSystem := NewPaymentSystem(charge, parkingTicket)
if err := paymentSystem.ProcessPayment(); err != nil {
return fmt.Errorf("payment failed: %v. Vehicle is still parked", err)
}
parkingTicket.Spot.RemoveVehicle()
parkingTicket.SetTotalCharge(charge)
parkingTicket.SetTicketStatus(Closed)
return nil
}