namespace AIStudio.Assistants.BeyondFactsLab;
///
/// What the agents of the BeyondFacts Lab found on the web about one person from the list of participants, stored as
/// research/participants/<id>.json in the folder of the step "Strategy", see BflPersonId.
///
///
///
/// The research on a person runs in stages, see BflPersonResearchStage. Each stage keeps its text together with what
/// left AI Studio for it, like the research on a topic, so that the person sees every query and every page.
///
///
/// A new research replaces the earlier one as soon as its first stage is done: then the research holds the stages of
/// the new run only, until it is complete. A research stopped before its first stage leaves the earlier one as it was.
///
///
public sealed class BflPersonResearch
{
///
/// The version of the stored form this version of AI Studio writes. Raise it with every new property.
///
public const int CURRENT_SCHEMA_VERSION = 1;
///
/// How many characters of the answer of the agent a stage keeps at most. The research on several people goes into
/// the prompt of the step "Strategy", so each stage stays well below the limit of a topic.
///
public const int MAX_STAGE_TEXT_CHARACTERS = 8_000;
///
/// Gets or sets the version of the stored form.
///
public int SchemaVersion { get; set; } = CURRENT_SCHEMA_VERSION;
///
/// Gets or sets the name of the person, as the list of participants gives it.
///
public string Name { get; set; } = string.Empty;
///
/// Gets or sets what the stages found, in the order in which they ran.
///
public List Stages { get; set; } = [];
///
/// Tells whether every stage is done.
///
public bool IsComplete => BflPersonResearchStage.All.All(stage => this.StageOf(stage) is not null);
///
/// Gets when the last stage was done, or null when none is.
///
public DateTimeOffset? LastCreatedAtUtc => this.Stages.Count is 0 ? null : this.Stages.Max(stage => stage.Research.CreatedAtUtc);
///
/// Gets what a stage found.
///
/// The stage.
/// The research of the stage, or null when the stage is not done.
public BflResearch? StageOf(BflPersonResearchStage stage) => this.Stages.FirstOrDefault(candidate => candidate.Stage == stage)?.Research;
///
/// Keeps what a stage found, in place of what it found before.
///
/// The stage.
/// What the stage found.
public void Set(BflPersonResearchStage stage, BflResearch research)
{
this.Stages.RemoveAll(candidate => candidate.Stage == stage);
this.Stages.Add(new BflPersonStageResearch { Stage = stage, Research = research });
this.Stages.Sort((first, second) => first.Stage.CompareTo(second.Stage));
}
///
/// Tells whether the public details about the event changed since one of the stages received them.
///
/// The public details as they are now, see BflPromptComposer.PublicDetailsOf.
public bool IsOutdated(IReadOnlyList details) => this.Stages.Any(stage => stage.Research.IsOutdated(details));
}