using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Vanara.Collections;
using Vanara.Extensions;
using Vanara.InteropServices;
using Vanara.PInvoke;
using static Vanara.PInvoke.BITS;
namespace Vanara.IO;
/// Provides information about a peer in the neighborhood.
public class CachePeer
{
private readonly ComReleaser ciPeer;
internal CachePeer(IBitsPeer peer) => ciPeer = ComReleaserFactory.Create(peer);
private CachePeer() => throw new NotImplementedException();
/// Determines whether the peer is authenticated.
/// if the peer is authenticated, otherwise, .
public bool IsAuthenticated => ciPeer.Item.IsAuthenticated();
/// Determines whether the peer is available (online) to serve content.
/// if the peer is available to serve content, otherwise, .
public bool IsAvailable => ciPeer.Item.IsAvailable();
/// Gets the server principal name that uniquely identifies the peer.
/// The server principal name of the peer. The principal name is of the form, server$.domain.suffix.
public string Name => ciPeer.Item.GetPeerName();
}
/// Provides the ability to enumerate the list of peers that BITS has discovered.
public class CachePeers : IReadOnlyCollection
{
private readonly IBitsPeerCacheAdministration iCacheAdmin;
internal CachePeers(IBitsPeerCacheAdministration admin) => iCacheAdmin = admin;
/// Gets the number of elements in the collection.
public int Count => EnumPeers().Count();
/// Removes all peers from the list of peers that can serve content.
public void Clear() => iCacheAdmin.ClearPeers();
/// Returns an enumerator that iterates through the collection.
/// An enumerator that can be used to iterate through the collection.
public IEnumerator GetEnumerator()
{
iCacheAdmin.DiscoverPeers();
return EnumPeers().GetEnumerator();
}
///
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
private IEnumerable EnumPeers()
{
IEnumBitsPeers ienum = iCacheAdmin.EnumPeers();
return ienum is null ? Enumerable.Empty() : IEnumFromCom.Create(ienum).Select(i => new CachePeer(i));
}
}
/// Use PeerCacheAdministration to manage the pool of peers from which you can download content.
public class PeerCacheAdministration
{
internal readonly ComReleaser ciCacheAdmin;
private CachePeers peers;
private PeerCacheRecords recs;
internal PeerCacheAdministration(IBackgroundCopyManager mgr) => ciCacheAdmin = ComReleaserFactory.Create((IBitsPeerCacheAdministration)mgr);
///
/// Gets or sets the configuration flags that determine if the computer serves content to peers and can download content from peers.
///
/// Flags that determine if the computer serves content to peers and can download content from peers.
public PeerCaching ConfigurationFlags
{
get => (PeerCaching)ciCacheAdmin.Item.GetConfigurationFlags();
set => ciCacheAdmin.Item.SetConfigurationFlags((BG_ENABLE_PEERCACHING)value);
}
/// Gets or sets the maximum size of the cache.
/// Maximum size of the cache, as a percentage of available hard disk drive space.
public uint MaximumCacheSize
{
get => ciCacheAdmin.Item.GetMaximumCacheSize();
set => ciCacheAdmin.Item.SetMaximumCacheSize(value);
}
/// Gets or sets the age by when files are removed from the cache.
/// Age. If the last time that the file was accessed is older than this age, BITS removes the file from the cache.
public TimeSpan MaximumContentAge
{
get => TimeSpan.FromSeconds(ciCacheAdmin.Item.GetMaximumContentAge());
set => ciCacheAdmin.Item.SetMaximumContentAge((uint)value.TotalSeconds);
}
/// Gets a instance that you use to enumerate the peers that can serve content.
/// A instance that you use to enumerate the peers that can serve content.
public CachePeers Peers => peers ??= new CachePeers(ciCacheAdmin.Item);
///
/// Gets a instance that you use to enumerate the records in the cache. The enumeration is a snapshot of
/// the records in the cache.
///
/// A instance that you use to enumerate the records in the cache.
public PeerCacheRecords Records => recs ??= new PeerCacheRecords(ciCacheAdmin.Item);
/// Deletes all cache records and the file from the cache for the given URL.
///
/// Null-terminated string that contains the URL of the file whose cache records and file you want to delete from the cache.
///
public void DeleteUrl(string url) => ciCacheAdmin.Item.DeleteUrl(url);
}
/// Provides the ability to enumerate the records of the cache.
public class PeerCacheRecords : IReadOnlyCollection
{
private readonly IBitsPeerCacheAdministration iCacheAdmin;
internal PeerCacheRecords(IBitsPeerCacheAdministration admin) => iCacheAdmin = admin;
/// Gets the number of elements in the collection.
public int Count => EnumRecords().Count();
/// Gets a record from the cache.
/// Identifier of the record to get from the cache.
/// A instance of the cache record.
public PeerCacheRecord this[Guid id] => new(iCacheAdmin.GetRecord(id));
/// Removes all the records and files from the cache.
public void Clear() => iCacheAdmin.ClearRecords();
/// Returns an enumerator that iterates through the collection.
/// An enumerator that can be used to iterate through the collection.
public IEnumerator GetEnumerator() => EnumRecords().GetEnumerator();
/// Deletes a record and file from the cache.
/// The record to delete from the cache.
public bool Remove(PeerCacheRecord item)
{ try { iCacheAdmin.DeleteRecord(item.Id); return true; } catch { return false; } }
///
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
private IEnumerable EnumRecords()
{
IEnumBitsPeerCacheRecords ienum = iCacheAdmin.EnumRecords();
return ienum is null ? Enumerable.Empty() : IEnumFromCom.Create(ienum).Select(i => new PeerCacheRecord(i));
}
}
/// Provides information about a file in the BITS peer cache.
public class PeerCacheRecord
{
private readonly ComReleaser ciRecord;
internal PeerCacheRecord(IBitsPeerCacheRecord bitsPeerCacheRecord) => ciRecord = ComReleaserFactory.Create(bitsPeerCacheRecord);
private PeerCacheRecord() => throw new NotImplementedException();
/// Gets the date and time that the file was last modified on the server.
/// Date and time that the file was last modified on the server.
public DateTime FileModificationTime => ciRecord.Item.GetFileModificationTime().ToDateTime();
/// Gets the ranges of the file that are in the cache.
/// Array of structures that specify the ranges of the file that are in the cache.
public BackgroundCopyFileRange[] FileRanges => Array.ConvertAll(ciRecord.Item.GetFileRanges(), i => (BackgroundCopyFileRange)i);
/// Gets the size of the file.
/// Size of the file, in bytes.
public ulong FileSize => ciRecord.Item.GetFileSize();
/// Gets the record identifier.
/// The identifier.
public Guid Id => ciRecord.Item.GetId();
/// Determines whether the file has been validated.
/// if file has been validated; otherwise .
public bool IsFileValidated => ciRecord.Item.IsFileValidated() == HRESULT.S_OK;
/// Gets the date and time that the file was last accessed.
/// Date and time that the file was last accessed.
public DateTime LastAccessTime => ciRecord.Item.GetLastAccessTime().ToDateTime();
/// Gets the origin URL of the cached file.
/// String that contains the origin URL of the cached file.
public string OriginUrl => ciRecord.Item.GetOriginUrl();
}