package thb.jeanluc.adventure.command.impl;

import org.junit.jupiter.api.Test;
import thb.jeanluc.adventure.game.GameContext;
import thb.jeanluc.adventure.io.TestIO;
import thb.jeanluc.adventure.model.Direction;
import thb.jeanluc.adventure.model.Player;
import thb.jeanluc.adventure.model.Room;
import thb.jeanluc.adventure.model.item.SwitchableItem;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

class DarknessTest {
    private SwitchableItem lamp(boolean on) {
        return SwitchableItem.builder().id("lamp").name("Lamp").description("d")
                .state(on).onText("on").offText("off").light(true).build();
    }

    @Test
    void cannotEnterDarkRoomWithoutLight() {
        Room hall = new Room("hall", "Hall", "d");
        Room cave = new Room("cave", "Cave", "d");
        cave.setDark(true);
        hall.addExit(Direction.NORTH, cave);
        Player p = new Player(hall, 0);
        GameContext ctx = new GameContext(null, p, new TestIO());

        new GoCommand().execute(ctx, List.of("north"));
        assertThat(p.getCurrentRoom()).isEqualTo(hall);
        assertThat(((TestIO) ctx.getIo()).allOutput()).containsIgnoringCase("pitch black");
    }

    @Test
    void canEnterDarkRoomWithLitLamp() {
        Room hall = new Room("hall", "Hall", "d");
        Room cave = new Room("cave", "Cave", "d");
        cave.setDark(true);
        hall.addExit(Direction.NORTH, cave);
        Player p = new Player(hall, 0);
        p.addItem(lamp(true));
        GameContext ctx = new GameContext(null, p, new TestIO());

        new GoCommand().execute(ctx, List.of("north"));
        assertThat(p.getCurrentRoom()).isEqualTo(cave);
    }

    @Test
    void lookAndTakeAreBlockedInTheDark() {
        Room cave = new Room("cave", "Cave", "d");
        cave.setDark(true);
        Player p = new Player(cave, 0);
        TestIO io = new TestIO();
        GameContext ctx = new GameContext(null, p, io);

        new LookCommand().execute(ctx, List.of());
        assertThat(io.allOutput()).containsIgnoringCase("pitch black");

        io.outputs().clear();
        new TakeCommand().execute(ctx, List.of("anything"));
        assertThat(io.allOutput()).containsIgnoringCase("too dark");
    }
}
