using AIStudio.Settings;
using AIStudio.Settings.DataModel;
namespace AIStudio.Tools.Services.Indexing;
///
/// The bounds of the random pause between two indexing steps, cf. PauseBetweenSteps.
///
/// The shortest pause. Between zero and MaximumSeconds.
/// The longest pause, which may be drawn as well. At most DataDataSourceIndexing.MAX_PAUSE_BETWEEN_STEPS_SECONDS.
internal sealed record PauseRange(int MinimumSeconds, int MaximumSeconds)
{
///
/// No pause at all, which is the default.
///
public static readonly PauseRange NONE = new(0, 0);
///
/// Whether the next step starts right away.
///
public bool IsNone => this.MaximumSeconds is 0;
///
/// The bounds which apply now, as the user set them and as configuration plugins lock them.
///
/// The settings of the indexing.
/// The bounds which apply.
public static PauseRange FromSettings(DataDataSourceIndexing settings)
{
var minimumSeconds = settings.MinimumPauseBetweenStepsSeconds;
var maximumSeconds = settings.MaximumPauseBetweenStepsSeconds;
//
// Which bound a configuration plugin locks matters only while the bounds are the wrong way
// round. Asking reads the managed state of the whole app, which bounds in order do without:
//
if (minimumSeconds <= maximumSeconds)
return GetEffective(minimumSeconds, false, maximumSeconds, false);
var isMinimumLocked = ManagedConfiguration.TryGet(x => x.App.DataSourceIndexing, x => x.MinimumPauseBetweenStepsSeconds, out var minimumMeta) && minimumMeta.IsLocked;
var isMaximumLocked = ManagedConfiguration.TryGet(x => x.App.DataSourceIndexing, x => x.MaximumPauseBetweenStepsSeconds, out var maximumMeta) && maximumMeta.IsLocked;
return GetEffective(minimumSeconds, isMinimumLocked, maximumSeconds, isMaximumLocked);
}
///
/// Works out the bounds which apply, so that the lower one never exceeds the upper one.
///
///
/// A bound which a configuration plugin locks wins, and the other one adjusts to it. A bound the
/// plugin only presets counts like one the user set. Otherwise, the lower bound wins, i.e., the
/// longer pause: it spares the embedding server, which is what the pause is for. That holds as
/// well when a plugin locks both bounds the wrong way round.
///
/// The lower bound as set.
/// Whether a configuration plugin locks the lower bound.
/// The upper bound as set.
/// Whether a configuration plugin locks the upper bound.
/// The bounds which apply.
public static PauseRange GetEffective(int minimumSeconds, bool isMinimumLocked, int maximumSeconds, bool isMaximumLocked)
{
var minimum = Math.Clamp(minimumSeconds, 0, DataDataSourceIndexing.MAX_PAUSE_BETWEEN_STEPS_SECONDS);
var maximum = Math.Clamp(maximumSeconds, 0, DataDataSourceIndexing.MAX_PAUSE_BETWEEN_STEPS_SECONDS);
if (isMaximumLocked && !isMinimumLocked)
return new(Math.Min(minimum, maximum), maximum);
return new(minimum, Math.Max(minimum, maximum));
}
}