package com.dne.ems.repository;

import java.util.List;
import java.util.Optional;

import com.dne.ems.model.Grid;

/**
 * Repository interface for accessing Grid data.
 * This acts as an abstraction layer over the data source,
 * which can be a database (JPA) or a JSON file.
 */
public interface GridRepository {

    /**
     * Retrieves all grid cells.
     *
     * @return a list of all Grid cells.
     */
    List<Grid> findAll();

    /**
     * Retrieves grid coverage statistics by city.
     *
     * @return a list of {@link com.dne.ems.dto.GridCoverageDTO} objects.
     */
    List<com.dne.ems.dto.GridCoverageDTO> getGridCoverageByCity();

    /**
     * Saves a given grid entity.
     * Use the returned instance for further operations as the save operation might have changed the
     * entity instance completely.
     *
     * @param grid must not be {@literal null}.
     * @return the saved entity; will never be {@literal null}.
     */
    Grid save(Grid grid);
    
    /**
     * Saves all given entities.
     *
     * @param entities must not be {@literal null} nor contain {@literal null}.
     * @return the saved entities; will never be {@literal null}. The returned {@link List} will have the same size as the
     *         input {@link Iterable}.
     * @throws IllegalArgumentException in case the given {@link Iterable entities} or one of its entities is
     *           {@literal null}.
     */
    List<Grid> saveAll(Iterable<Grid> entities);

    /**
     * Finds a grid cell by its ID.
     *
     * @param id The ID of the grid.
     * @return An {@link Optional} containing the found grid cell, or {@link Optional#empty()} if not found.
     */
    Optional<Grid> findById(Long id);

    /**
     * Finds a grid cell by its X and Y coordinates.
     *
     * @param gridX The X coordinate of the grid.
     * @param gridY The Y coordinate of the grid.
     * @return An {@link Optional} containing the found grid cell, or {@link Optional#empty()} if not found.
     */
    Optional<Grid> findByGridXAndGridY(Integer gridX, Integer gridY);

    /**
     * Finds all grid cells by their obstacle status.
     *
     * @param isObstacle The obstacle status to search for.
     * @return A list of grids matching the obstacle status.
     */
    List<Grid> findByIsObstacle(boolean isObstacle);
    
    /**
     * Returns the number of entities available.
     *
     * @return the number of entities.
     */
    long count();
} 