using System;
using System.Collections.Generic;

namespace Interfaces
{
    public interface IRepository
    {
        /// <summary>
        /// Get a list of Users
        /// </summary>
        /// <returns>
        /// Returns <see cref="UserList"/> with full list of users,
        /// plus a total user count. Pagination options are supported.
        /// </returns>
        UserList GetUsers(int pageNumber = -1, int pageSize = -1, int groupId = -1);
        /// <summary>
        /// Search the user list for the following string
        /// </summary>
        /// <param name="searchParam">string to search the user store for.</param>
        /// <returns>
        /// Returns <see cref="UserList"/> with full list of users,
        /// plus a total user count. Pagination options are supported.
        /// </returns>
        UserList Search(string searchParam);
        /// <summary>
        /// Get details about a single user in the system base on their Id
        /// </summary>
        /// <param name="id">
        /// integer data type, the Id of the User to get details about.</param>
        /// <returns>
        /// <see cref="User"/> object with full details, 
        /// including full <see cref="Identifier"/>
        /// </returns>
        User GetUser(int id);
        /// <summary>
        /// Get a list of the timelogs available for the specified user
        /// for the current Calendar Week
        /// </summary>
        /// <param name="userId">
        /// integer data type, the Id of the user to get time logs for
        /// </param>
        /// <returns>
        /// <see cref="TimeLogList"/> with nested <see cref="TimeLog"/> objects
        /// for the current calendar week
        /// </returns>
        TimeLogList GetTimeLogs(int userId);
        /// <summary>
        /// Get a list of the timelogs available for the specified user
        /// for the specified calendar week
        /// </summary>
        /// <param name="userId">
        /// integer data type, the Id of the user to get time logs for
        /// </param>
        /// <param name="selectedDate">
        /// datetime data type, the date to receive time logs for (will scope out to calendar week).
        /// </param>
        /// <returns>
        /// <see cref="TimeLogList"/> with nested <see cref="TimeLog"/> objects
        /// for the current calendar week
        /// </returns>
        TimeLogList GetTimeLogs(int userId, DateTime selectedDate);
        /// <summary>
        /// Get a full list of Identifiers which are not associated to a user.
        /// </summary>
        /// <returns>
        /// <see cref="IdentifierList"/> with nested <see cref="Identifier"/> list
        /// </returns>
        IdentifierList GetUnassignedIdentifierList();

        /// <summary>
        /// Update a user in the system with the new values.
        /// </summary>
        /// <remarks>
        /// If the user object passed does not exist, it will be created.
        /// </remarks>
        /// <param name="user">
        /// <see cref="User"/> object detailing the new properties to assign to the user.
        /// The Id Field should not be changed, or should be -1 for new users.
        /// </param>
        /// <param name="userId">
        /// int - ref param, value will be the UserId of the inserted or updated user
        /// </param>
        /// <returns>
        /// <see cref="OperationResponse"/> to indicate procedure status.
        /// </returns>
        OperationResponse UpdateUser(User user, out int userId);

        /// <summary>
        /// Create a new TimeLog Event in the repository.
        /// </summary>
        /// <param name="identifier">
        /// <see cref="Identifier"/> object with the Unique Id triggering the event
        /// </param>
        /// <param name="logId">The resultant Id of the inserted TimeLog</param>
        /// <returns>
        /// <see cref="OperationResponse"/> to indicate procedure status.
        /// </returns>
        LogEventResponse LogEventTime(Identifier identifier, out int logId);

        OperationResponse CreateGroup(Group group, out int groupId);
        List<Group> GetGroups(int userId = -1);
        Group GetGroup(int groupId);
        OperationResponse UpdateGroup(Group group);
        OperationResponse DeleteGroup(int groupId);

        OperationResponse DeleteLog(TimeLog log);
        OperationResponse CreateLog(TimeLog log);
        OperationResponse UpdateLog(TimeLog log);
    }
}
