﻿// MIT License. Copyright (c) 2016 Maxim Kuzmin. Contacts: https://github.com/maxim-kuzmin

// Author: Maxim Kuzmin

using Makc2016.Core.Caching;
using Makc2016.Core.Caching.Clients;
using Makc2016.Core.Execution.Operations.Async;
using Makc2016.Data.Objects;
using Makc2016.Modules.Role.Filters;
using Makc2016.Modules.Role.Models;
using Makc2016.Modules.Role.Operations.Item;
using System;
using System.Threading.Tasks;

namespace Makc2016.Modules.Role.Caching.Operations.Item
{
    /// <summary>
    /// Модули. Модуль "Role". Кэширование. Операции. Операция, выполняющая функцию получения элемента.
    /// </summary>
    public class ModuleRoleCachingOperationItemGet : CoreExecutionOperationAsyncWithInputAndOutputData
        <
            ModuleRoleFilterItem,
            ModuleRoleModelItem
        >
    {
        #region Constructors

        /// <summary>
        /// Конструктор.
        /// </summary>
        /// <param name="operation">Операция, содержащая выполняемую функцию.</param>   
        /// <param name="config">Конфигурация.</param>        
        /// <param name="cache">Кэш.</param>        
        public ModuleRoleCachingOperationItemGet(
            ModuleRoleOperationItemGet operation,
            ICoreCachingClientConfig config,
            ICoreCachingCache cache            
            ) : base(
                CreateExecutableFunction(operation, config, cache),
                operation.FuncErrorMessagesGetting,
                operation.FuncInputDataTransform,
                operation.FuncSuccessMessagesGetting,
                operation.FuncWarningMessagesGetting
                )
        {
        }

        #endregion Constructors

        #region Private methods

        /// <summary>
        /// Создать выполняемую функцию.
        /// </summary>
        /// <returns>Выполняемая функция.</returns>
        private static Func<ModuleRoleFilterItem, Task<ModuleRoleModelItem>> CreateExecutableFunction(
            ModuleRoleOperationItemGet operation,
            ICoreCachingClientConfig config,
            ICoreCachingCache cache
            )
        {
            if (config.IsCachingEnabled)
            {
                var client = new CoreCachingClientWithChangeAndRead<ModuleRoleModelItem>(
                    "Item.Get",
                    config,
                    cache
                    );

                return inputData =>
                {
                    var keys = new object[]
                    {
                        inputData.Id
                    };

                    var tags = new[]
                    {
                        DataObjectRole.DB_TABLE_NAME_WITH_SCHEMA
                    };

                    return client.Read(() => operation.ExecutableFunction(inputData), keys, tags);
                };
            }
            else
            {
                return operation.ExecutableFunction;
            }
        }

        #endregion Private methods
    }
}
