using System;
using System.Collections.Generic;
using System.Linq;
namespace Unosquare.Swan.Networking.Ldap {
///
/// An LdapSearchResults object is returned from a synchronous search
/// operation. It provides access to all results received during the
/// operation (entries and exceptions).
///
///
public sealed class LdapSearchResults {
private readonly List _messages;
private readonly Int32 _messageId;
///
/// Initializes a new instance of the class.
///
/// The messages.
/// The message identifier.
internal LdapSearchResults(List messages, Int32 messageId) {
this._messages = messages;
this._messageId = messageId;
}
///
/// Returns a count of the items in the search result.
/// Returns a count of the entries and exceptions remaining in the object.
/// If the search was submitted with a batch size greater than zero,
/// getCount reports the number of results received so far but not enumerated
/// with next(). If batch size equals zero, getCount reports the number of
/// items received, since the application thread blocks until all results are
/// received.
///
///
/// The count.
///
public Int32 Count => new List(this._messages)
.Count(x => x.MessageId == this._messageId && GetResponse(x) is LdapSearchResult);
///
/// Reports if there are more search results.
///
///
/// true if there are more search results.
///
public Boolean HasMore() => new List(this._messages)
.Any(x => x.MessageId == this._messageId && GetResponse(x) is LdapSearchResult);
///
/// Returns the next result as an LdapEntry.
/// If automatic referral following is disabled or if a referral
/// was not followed, next() will throw an LdapReferralException
/// when the referral is received.
///
///
/// The next search result as an LdapEntry.
///
/// Next - No more results.
public LdapEntry Next() {
IEnumerable list = new List(this._messages)
.Where(x => x.MessageId == this._messageId);
foreach(RfcLdapMessage item in list) {
_ = this._messages.Remove(item);
LdapMessage response = GetResponse(item);
if(response is LdapSearchResult result) {
return result.Entry;
}
}
throw new ArgumentOutOfRangeException(nameof(Next), "No more results");
}
private static LdapMessage GetResponse(RfcLdapMessage item) {
switch(item.Type) {
case LdapOperation.SearchResponse:
return new LdapSearchResult(item);
case LdapOperation.SearchResultReference:
return new LdapSearchResultReference(item);
default:
return new LdapResponse(item);
}
}
}
}