////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////

package pp.battleship;

import pp.util.config.Config;

import java.util.Map;
import java.util.TreeMap;

import static java.lang.Math.max;

/**
 * Provides access to the configuration settings for the Battleship game.
 * <p>
 * This class allows for loading configuration settings from a properties file,
 * including the server port, map dimensions, and the number of ships of various lengths.
 * </p>
 * <p>
 * <b>Note:</b> Attributes of this class are not marked as {@code final} to allow
 * for proper initialization when reading from a properties file.
 * </p>
 */
public class BattleshipConfig extends Config {

    /**
     * The default port number for the Battleship server.
     */
    @Property("port")
    private int port = 1234;

    /**
     * The width of the game map in terms of grid units.
     */
    @Property("map.width")
    private int mapWidth = 10;

    /**
     * The height of the game map in terms of grid units.
     */
    @Property("map.height")
    private int mapHeight = 10;

    /**
     * An array representing the number of ships available for each length.
     * The index corresponds to the ship length minus one, and the value at each index
     * is the number of ships of that length.
     */
    @Property("ship.nums")
    private int[] shipNums = {4, 3, 2, 1};

    /**
     * Creates an instance of {@code BattleshipConfig} with default settings.
     */
    public BattleshipConfig() {
        // Default constructor
    }

    /**
     * Returns the port number configured for the Battleship server.
     *
     * @return the port number
     */
    public int getPort() {
        return port;
    }

    /**
     * Returns the width of the game map. The width is guaranteed to be at least 2 units.
     *
     * @return the width of the game map
     */
    public int getMapWidth() {
        return max(mapWidth, 2);
    }

    /**
     * Returns the height of the game map. The height is guaranteed to be at least 2 units.
     *
     * @return the height of the game map
     */
    public int getMapHeight() {
        return max(mapHeight, 2);
    }

    /**
     * Returns a map representing the number of ships for each length.
     * The keys are ship lengths, and the values are the corresponding number of ships.
     *
     * @return a map of ship lengths to the number of ships
     */
    public Map<Integer, Integer> getShipNums() {
        final TreeMap<Integer, Integer> ships = new TreeMap<>();
        for (int i = 0; i < shipNums.length; i++)
            if (shipNums[i] > 0)
                ships.put(i + 1, shipNums[i]);
        return ships;
    }
}
