package cz.jzitnik.game;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import lombok.extern.slf4j.Slf4j;

import java.io.*;

/**
 * Handles saving and loading the game state using Kryo serialization.
 */
@Slf4j
public class GameSaver {

    private static final String SAVE_FILE = "world.ser";

    private final Kryo kryo;

    /**
     * Initializes the GameSaver with Kryo serialization setup.
     */
    public GameSaver() {
        this.kryo = new Kryo();
        kryo.setRegistrationRequired(false);
        kryo.setReferences(true);
    }

    /**
     * Saves the current game state to a file.
     *
     * @param game the game instance to be saved
     */
    public void save(Game game) {
        try (Output output = new Output(new FileOutputStream(SAVE_FILE))) {
            kryo.writeClassAndObject(output, game);
        } catch (IOException e) {
            log.error("Failed to save game", e);
        }
    }

    /**
     * Loads the game state from a file. If the save file does not exist,
     * a new game instance is returned.
     *
     * @return the loaded game instance or a new game if no save is found
     */
    public Game load() {
        log.info("Loading game");

        File file = new File(SAVE_FILE);
        if (!file.isFile()) {
            log.info("No save file found, creating new game");
            return new Game();
        }

        try (Input input = new Input(new FileInputStream(SAVE_FILE))) {
            log.info("Loading game from save file");
            Object object = kryo.readClassAndObject(input);
            return (Game) object;
        } catch (IOException e) {
            log.error("Failed to load game", e);
            throw new RuntimeException(e);
        }
    }
}
