/*
 * Copyright 2025 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System.Collections.Generic;

namespace Firebase.AI
{
  /// Settings for controlling the aggressiveness of filtering out sensitive content.
  ///
  /// See the [Responsible AI and usage
  /// guidelines](https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#config-safety-filters)
  /// for more details.
  public readonly struct ImagenSafetySettings
  {

    /// <summary>
    /// A filter level controlling how aggressively to filter sensitive content.
    ///
    /// Text prompts provided as inputs and images (generated or uploaded) through Imagen on Vertex AI
    /// are assessed against a list of safety filters, which include 'harmful categories' (for example,
    /// `violence`, `sexual`, `derogatory`, and `toxic`). This filter level controls how aggressively to
    /// filter out potentially harmful content from responses. See the
    /// [`safetySetting`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api#parameter_list)
    /// documentation and the [Responsible AI and usage
    /// guidelines](https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#safety-filters)
    /// for more details.
    /// </summary>
    public enum SafetyFilterLevel
    {
      /// <summary>
      /// The most aggressive filtering level; most strict blocking.
      /// </summary>
      BlockLowAndAbove,
      /// <summary>
      /// Blocks some problematic prompts and responses.
      /// </summary>
      BlockMediumAndAbove,
      /// <summary>
      /// Reduces the number of requests blocked due to safety filters.
      ///
      /// > Important: This may increase objectionable content generated by Imagen.
      /// </summary>
      BlockOnlyHigh,
      /// <summary>
      /// The least aggressive filtering level; blocks very few problematic prompts and responses.
      ///
      /// > Important: Access to this feature is restricted and may require your use case to be reviewed
      /// and approved by Cloud support.
      /// </summary>
      BlockNone
    }

    /// <summary>
    /// A filter level controlling whether generation of images containing people or faces is allowed.
    ///
    /// See the
    /// [`personGeneration`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api#parameter_list)
    /// documentation for more details.
    /// </summary>
    public enum PersonFilterLevel
    {
      /// <summary>
      /// Disallow generation of images containing people or faces; images of people are filtered out.
      /// </summary>
      BlockAll,
      /// <summary>
      /// Allow generation of images containing adults only; images of children are filtered out.
      ///
      /// > Important: Generation of images containing people or faces may require your use case to be
      /// reviewed and approved by Cloud support; see the [Responsible AI and usage
      /// guidelines](https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#person-face-gen)
      /// for more details.
      /// </summary>
      AllowAdult,
      /// <summary>
      /// Allow generation of images containing people of all ages.
      ///
      /// > Important: Generation of images containing people or faces may require your use case to be
      /// reviewed and approved; see the [Responsible AI and usage
      /// guidelines](https://cloud.google.com/vertex-ai/generative-ai/docs/image/responsible-ai-imagen#person-face-gen)
      /// for more details.
      /// </summary>
      AllowAll
    }

#if !DOXYGEN
    public SafetyFilterLevel? SafetyFilter { get; }
    public PersonFilterLevel? PersonFilter { get; }
#endif

    /// <summary>
    /// Initializes safety settings for the Imagen model.
    /// </summary>
    /// <param name="safetyFilterLevel">A filter level controlling how aggressively to
    ///     filter out sensitive content from generated images.</param>
    /// <param name="personFilterLevel">A filter level controlling whether generation
    ///     of images containing people or faces is allowed.</param>
    public ImagenSafetySettings(
        SafetyFilterLevel? safetyFilterLevel = null,
        PersonFilterLevel? personFilterLevel = null)
    {
      SafetyFilter = safetyFilterLevel;
      PersonFilter = personFilterLevel;
    }

    private static string ConvertSafetyFilter(SafetyFilterLevel safetyFilter)
    {
      return safetyFilter switch
      {
        SafetyFilterLevel.BlockLowAndAbove => "block_low_and_above",
        SafetyFilterLevel.BlockMediumAndAbove => "block_medium_and_above",
        SafetyFilterLevel.BlockOnlyHigh => "block_only_high",
        SafetyFilterLevel.BlockNone => "block_none",
        _ => safetyFilter.ToString(), // Fallback
      };
    }

    private static string ConvertPersonFilter(PersonFilterLevel safetyFilter)
    {
      return safetyFilter switch
      {
        PersonFilterLevel.BlockAll => "dont_allow",
        PersonFilterLevel.AllowAdult => "allow_adult",
        PersonFilterLevel.AllowAll => "allow_all",
        _ => safetyFilter.ToString(), // Fallback
      };
    }

    /// <summary>
    /// Intended for internal use only.
    /// This method is used for serializing the object to JSON for the API request.
    /// </summary>
    internal Dictionary<string, object> ToJson()
    {
      Dictionary<string, object> jsonDict = new();

      if (PersonFilter != null)
      {
        jsonDict["personGeneration"] = ConvertPersonFilter(PersonFilter.Value);
      }
      if (SafetyFilter != null)
      {
        jsonDict["safetySetting"] = ConvertSafetyFilter(SafetyFilter.Value);
      }

      return jsonDict;
    }
  }

}
