private static WalletDto ConvertEntityToDto(BlockchainWalletEntity entity)
 {
     return(new WalletDto
     {
         Address = entity.Address,
         BlockchainType = entity.IntegrationLayerId,
         ClientId = entity.ClientId,
         CreatorType = entity.CreatedBy
     });
 }
        //clientLatestDepositIndexManualPartitionKey let it be null for common operations
        public async Task AddAsync(string blockchainType, Guid clientId, string address,
                                   CreatorType createdBy, string clientLatestDepositIndexManualPartitionKey = null, bool addAsLatest = true)
        {
            var partitionKey = BlockchainWalletEntity.GetPartitionKey(blockchainType, clientId);
            var rowKey       = BlockchainWalletEntity.GetRowKey(address);

            var clientLatestDepositIndexPartitionKey = GetClientLatestIndexPartitionKey(clientId);
            var clientLatestDepositIndexRowKey       = GetClientLatestIndexRowKey(blockchainType);

            var(indexPartitionKey, indexRowKey) = GetAddressIndexKeys(blockchainType, address);
            var(clientBtIndexPartitionKey, clientBtIndexRowKey) = GetClientBlockchainTypeIndexKeys(blockchainType, clientId);

            clientBtIndexRowKey = clientLatestDepositIndexManualPartitionKey ?? clientBtIndexRowKey;

            await _addressIndexTable.InsertOrReplaceAsync(new AzureIndex(
                                                              indexPartitionKey,
                                                              indexRowKey,
                                                              partitionKey,
                                                              rowKey
                                                              ));

            await _clientBlockchainTypeIndexTable.InsertOrReplaceAsync(new AzureIndex(
                                                                           clientBtIndexPartitionKey,
                                                                           clientBtIndexRowKey,
                                                                           partitionKey,
                                                                           rowKey
                                                                           ));

            if (addAsLatest)
            {
                await _clientLatestDepositsIndexTable.InsertOrReplaceAsync(new AzureIndex(
                                                                               clientLatestDepositIndexPartitionKey,
                                                                               clientLatestDepositIndexRowKey,
                                                                               partitionKey,
                                                                               rowKey
                                                                               ));
            }

            // Wallet entity

            await _walletsTable.InsertOrReplaceAsync(new BlockchainWalletEntity
            {
                PartitionKey = partitionKey,
                RowKey       = rowKey,

                Address            = address,
                ClientId           = clientId,
                IntegrationLayerId = blockchainType,
                CreatedBy          = createdBy
            });
        }
 private static (string PartitionKey, string RowKey) GetAddressIndexKeys(BlockchainWalletEntity wallet)
 {
     return(GetAddressIndexKeys(wallet.IntegrationLayerId, wallet.Address));
 }
 private static (string PartitionKey, string RowKey) GetClientIndexKeys(BlockchainWalletEntity wallet)
 {
     return(GetClientIndexKeys(wallet.ClientId));
 }
        public async Task DeleteIfExistsAsync(string blockchainType, Guid clientId, string address)
        {
            var partitionKey = BlockchainWalletEntity.GetPartitionKey(blockchainType, clientId);
            var rowKey       = BlockchainWalletEntity.GetRowKey(address);

            var(indexPartitionKey, indexRowKey) = GetAddressIndexKeys(blockchainType, address);
            var addressIndex = await _addressIndexTable.GetDataAsync(indexPartitionKey, indexRowKey);

            var clientLatestDepositIndexPartitionKey = GetClientLatestIndexPartitionKey(clientId);
            var clientLatestDepositIndexRowKey       = GetClientLatestIndexRowKey(blockchainType);

            var latestDeposit = await _clientLatestDepositsIndexTable.GetDataAsync(clientLatestDepositIndexPartitionKey,
                                                                                   clientLatestDepositIndexRowKey);

            var wallet = await _walletsTable.GetDataAsync(partitionKey, rowKey);

            var(clientBtIndexPartitionKey, clientBtIndexRowKey) = GetClientBlockchainTypeIndexKeys(blockchainType, clientId);

            await _archiveTable.InsertOrReplaceAsync(wallet);

            await _clientBlockchainTypeIndexTable.DeleteIfExistAsync(clientBtIndexPartitionKey, clientBtIndexRowKey);

            await _addressIndexTable.DeleteIfExistAsync(indexPartitionKey, indexRowKey);

            if (wallet?.Address == latestDeposit?.PrimaryRowKey)
            {
                await _clientLatestDepositsIndexTable.DeleteIfExistAsync(clientLatestDepositIndexPartitionKey,
                                                                         clientLatestDepositIndexRowKey,
                                                                         (index) => latestDeposit?.ETag == index.ETag);

                AzureIndex newMostRecent = null;
                string     cToken        = null;

                do
                {
                    var previousDeposits =
                        await GetClientBlockchainTypeIndices(blockchainType, clientId, _batchSize, cToken);

                    var toDelete = previousDeposits.Entities.FirstOrDefault(x => x.PrimaryRowKey == latestDeposit?.PrimaryRowKey);
                    if (!string.IsNullOrEmpty(toDelete.PrimaryRowKey) &&
                        !string.IsNullOrEmpty(toDelete.PrimaryPartitionKey))
                    {
                        await _clientBlockchainTypeIndexTable.DeleteIfExistAsync(toDelete.PartitionKey, toDelete.RowKey);
                    }
                    if (newMostRecent == null)
                    {
                        newMostRecent = previousDeposits.Entities.FirstOrDefault(x => x.PrimaryRowKey != latestDeposit?.PrimaryRowKey);
                    }
                } while (cToken != null);


                if (newMostRecent != null)
                {
                    await _clientLatestDepositsIndexTable.InsertOrReplaceAsync(new AzureIndex(
                                                                                   clientLatestDepositIndexPartitionKey,
                                                                                   clientLatestDepositIndexRowKey,
                                                                                   newMostRecent.PrimaryPartitionKey,
                                                                                   newMostRecent.PrimaryRowKey));
                }
            }
            else
            {
                string cToken = null;

                do
                {
                    var previousDeposits =
                        await  GetClientBlockchainTypeIndices(blockchainType, clientId, _batchSize, cToken);

                    var toDelete = previousDeposits.Entities.FirstOrDefault(x => x.PrimaryRowKey == wallet?.Address);
                    if (toDelete != null &&
                        !string.IsNullOrEmpty(toDelete.PrimaryPartitionKey) &&
                        !string.IsNullOrEmpty(toDelete.PrimaryRowKey))
                    {
                        await _clientBlockchainTypeIndexTable.DeleteIfExistAsync(toDelete.PartitionKey, toDelete.RowKey);

                        break;
                    }
                } while (cToken != null);
            }

            await _walletsTable.DeleteIfExistAsync(wallet?.PartitionKey, wallet?.RowKey);
        }