// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Compliance.Redaction;
using Microsoft.Shared.DiagnosticIds;

namespace Microsoft.Agents.AI.Foundry;

/// <summary>
/// Options for configuring the <see cref="FoundryMemoryProvider"/>.
/// </summary>
[Experimental(DiagnosticIds.Experiments.AgentsAIExperiments)]
public sealed class FoundryMemoryProviderOptions
{
    /// <summary>
    /// When providing memories to the model, this string is prefixed to the retrieved memories to supply context.
    /// </summary>
    /// <value>Defaults to "## Memories\nConsider the following memories when answering user questions:".</value>
    public string? ContextPrompt { get; set; }

    /// <summary>
    /// Gets or sets the maximum number of memories to retrieve during search.
    /// </summary>
    /// <value>Defaults to 5.</value>
    public int MaxMemories { get; set; } = 5;

    /// <summary>
    /// Gets or sets the delay in seconds before memory updates are processed.
    /// </summary>
    /// <remarks>
    /// Setting to 0 triggers updates immediately without waiting for inactivity.
    /// Higher values allow the service to batch multiple updates together.
    /// </remarks>
    /// <value>Defaults to 0 (immediate).</value>
    public int UpdateDelay { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether sensitive data such as user ids and user messages may appear in logs.
    /// </summary>
    /// <value>Defaults to <see langword="false"/>.</value>
    /// <remarks>
    /// When set to <see langword="true"/>, sensitive data is passed through to logs unchanged and any
    /// configured <see cref="Redactor"/> is ignored. This property takes precedence over <see cref="Redactor"/>.
    /// </remarks>
    public bool EnableSensitiveTelemetryData { get; set; }

    /// <summary>
    /// Gets or sets a custom <see cref="Redactor"/> used to redact sensitive data in log output.
    /// </summary>
    /// <value>
    /// When <see langword="null"/> (the default), sensitive data is replaced with a placeholder.
    /// When set, this redactor is used to transform sensitive values before they are logged.
    /// Ignored when <see cref="EnableSensitiveTelemetryData"/> is <see langword="true"/>.
    /// </value>
    public Redactor? Redactor { get; set; }

    /// <summary>
    /// Gets or sets the key used to store the provider state in the session's <see cref="AgentSessionStateBag"/>.
    /// </summary>
    /// <value>Defaults to the provider's type name.</value>
    public string? StateKey { get; set; }

    /// <summary>
    /// Gets or sets an optional filter function applied to request messages when building the search text to use when
    /// searching for relevant memories during <see cref="AIContextProvider.InvokingAsync"/>.
    /// </summary>
    /// <value>
    /// When <see langword="null"/>, the provider defaults to including only
    /// <see cref="AgentRequestMessageSourceType.External"/> messages.
    /// </value>
    public Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? SearchInputMessageFilter { get; set; }

    /// <summary>
    /// Gets or sets an optional filter function applied to request messages when determining which messages to
    /// extract memories from during <see cref="AIContextProvider.InvokedAsync"/>.
    /// </summary>
    /// <value>
    /// When <see langword="null"/>, the provider defaults to including only
    /// <see cref="AgentRequestMessageSourceType.External"/> messages.
    /// </value>
    public Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? StorageInputRequestMessageFilter { get; set; }

    /// <summary>
    /// Gets or sets an optional filter function applied to response messages when determining which messages to
    /// extract memories from during <see cref="AIContextProvider.InvokedAsync"/>.
    /// </summary>
    /// <value>
    /// When <see langword="null"/>, the provider does not filter response messages and includes all messages.
    /// </value>
    public Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? StorageInputResponseMessageFilter { get; set; }
}
