type TrafficLight =
    | Red
    | Yellow
    | Green

fn nextLight(light: TrafficLight): TrafficLight =
    match light {
    Red => Green,
    Green => Yellow,
    Yellow => Red,
}

fn canGo(light: TrafficLight): Bool =
    match light {
    Green => true,
    Yellow => false,
    Red => false,
}

fn lightColor(light: TrafficLight): String =
    match light {
    Red => "red",
    Yellow => "yellow",
    Green => "green",
}

type DoorState =
    | Open
    | Closed
    | Locked

type DoorAction =
    | OpenDoor
    | CloseDoor
    | LockDoor
    | UnlockDoor

fn applyAction(state: DoorState, action: DoorAction): DoorState =
    match (state, action) {
    (Closed, OpenDoor) => Open,
    (Open, CloseDoor) => Closed,
    (Closed, LockDoor) => Locked,
    (Locked, UnlockDoor) => Closed,
    _ => state,
}

fn doorStateName(state: DoorState): String =
    match state {
    Open => "Open",
    Closed => "Closed",
    Locked => "Locked",
}

let light1 = Red

let light2 = nextLight(light1)

let light3 = nextLight(light2)

let door1 = Closed

let door2 = applyAction(door1, OpenDoor)

let door3 = applyAction(door2, CloseDoor)

let door4 = applyAction(door3, LockDoor)

fn printResults(): Unit with {Console} = {
    Console.print("Initial light: " + lightColor(light1))
    Console.print("After transition: " + lightColor(light2))
    Console.print("After two transitions: " + lightColor(light3))
    Console.print("Door: " + doorStateName(door1) + " -> " + doorStateName(door2) + " -> " + doorStateName(door3) + " -> " + doorStateName(door4))
}

let output = run printResults() with {}
