using System;
using System.Collections.Generic;
using InABox.Core;

namespace InABox.Clients
{
    
    
    public interface IClient : IQueryProvider
    {
        IValidationData Validate(string userid, string password, Guid session = default);
        IValidationData Validate(string pin, Guid session = default);
        IValidationData Validate(Guid session);

        CoreTable Query(object? filter = null, object? columns = null, object? sort = null, CoreRange? range = null);
        Entity[] Load(object? filter = null, object? sort = null, CoreRange? range = null);
        void Save(object entity, string auditnote);
        void Save(IEnumerable<object> entities, string auditnote);
        void Delete(object entity, string auditnote);
        void Delete(IEnumerable<object> entities, string auditnote);
        Dictionary<string, CoreTable> QueryMultiple(Dictionary<string, IQueryDef> queries);
        void QueryMultiple(Action<Dictionary<string, CoreTable>?, Exception?> callback, Dictionary<string, IQueryDef> queries);

        bool Check2FA(string code, Guid? session = null);

        /// <summary>
        /// Check if the server is running
        /// </summary>
        /// <returns><c>true</c> if the server is running</returns>
        bool Ping();
        
        /// <summary>
        /// Get general information about this server
        /// </summary>
        /// <returns>DatabaseInfo</returns>
        DatabaseInfo? Info();

        string Version();

        string ReleaseNotes();

        byte[]? Installer();


        IEnumerable<string> SupportedTypes();
        
        event LogEvent OnLog;

        bool IsConnected();

    }

    public interface IClient<TEntity> : IClient, IQueryProvider<TEntity> where TEntity : Entity, new()
    {
        TEntity[] Load(Filter<TEntity>? filter = null, SortOrder<TEntity>? sort = null, CoreRange? range = null);
        void Load(Filter<TEntity>? filter, SortOrder<TEntity>? sort, CoreRange? range, Action<TEntity[]?, Exception?> callback);
    }

}