// <copyright file="BaseItemManagerTests.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>

namespace Jellyfin.Controller.Tests
{
    using System;
    using MediaBrowser.Controller.BaseItemManager;
    using MediaBrowser.Controller.Configuration;
    using MediaBrowser.Controller.Entities;
    using MediaBrowser.Controller.Entities.Audio;
    using MediaBrowser.Model.Configuration;
    using Moq;
    using Xunit;

    /// <summary>
    /// Tests for <see cref="BaseItemManager"/>.
    /// </summary>
    public class BaseItemManagerTests
    {
        /// <summary>
        /// Tests that IsMetadataFetcherEnabled checks library and server configuration options.
        /// </summary>
        /// <param name="itemType">The type of item to test.</param>
        /// <param name="fetcherName">The name of the metadata fetcher.</param>
        /// <param name="expected">The expected result.</param>
        [Theory]
        [InlineData(typeof(Book), "LibraryEnabled", true)]
        [InlineData(typeof(Book), "LibraryDisabled", false)]
        [InlineData(typeof(MusicArtist), "Enabled", true)]
        [InlineData(typeof(MusicArtist), "ServerDisabled", false)]
        public void IsMetadataFetcherEnabled_ChecksOptions_ReturnsExpected(Type itemType, string fetcherName, bool expected)
        {
            BaseItem item = (BaseItem)Activator.CreateInstance(itemType)!;

            TypeOptions? libraryTypeOptions = itemType == typeof(Book)
                ? new TypeOptions
                {
                    Type = "Book",
                    MetadataFetchers = ["LibraryEnabled"],
                }
                : null;

            ServerConfiguration serverConfiguration = new();
            foreach (MetadataOptions typeConfig in serverConfiguration.MetadataOptions)
            {
                typeConfig.DisabledMetadataFetchers = ["ServerDisabled"];
            }

            Mock<IServerConfigurationManager> serverConfigurationManager = new();
            _ = serverConfigurationManager.Setup(scm => scm.Configuration)
                .Returns(serverConfiguration);

            BaseItemManager baseItemManager = new(serverConfigurationManager.Object);
            bool actual = baseItemManager.IsMetadataFetcherEnabled(item, libraryTypeOptions, fetcherName);

            Assert.Equal(expected, actual);
        }

        /// <summary>
        /// Tests that IsImageFetcherEnabled checks library and server configuration options.
        /// </summary>
        /// <param name="itemType">The type of item to test.</param>
        /// <param name="fetcherName">The name of the image fetcher.</param>
        /// <param name="expected">The expected result.</param>
        [Theory]
        [InlineData(typeof(Book), "LibraryEnabled", true)]
        [InlineData(typeof(Book), "LibraryDisabled", false)]
        [InlineData(typeof(MusicArtist), "Enabled", true)]
        [InlineData(typeof(MusicArtist), "ServerDisabled", false)]
        public void IsImageFetcherEnabled_ChecksOptions_ReturnsExpected(Type itemType, string fetcherName, bool expected)
        {
            BaseItem item = (BaseItem)Activator.CreateInstance(itemType)!;

            TypeOptions? libraryTypeOptions = itemType == typeof(Book)
                ? new TypeOptions
                {
                    Type = "Book",
                    ImageFetchers = ["LibraryEnabled"],
                }
                : null;

            ServerConfiguration serverConfiguration = new();
            foreach (MetadataOptions typeConfig in serverConfiguration.MetadataOptions)
            {
                typeConfig.DisabledImageFetchers = ["ServerDisabled"];
            }

            Mock<IServerConfigurationManager> serverConfigurationManager = new();
            _ = serverConfigurationManager.Setup(scm => scm.Configuration)
                .Returns(serverConfiguration);

            BaseItemManager baseItemManager = new(serverConfigurationManager.Object);
            bool actual = baseItemManager.IsImageFetcherEnabled(item, libraryTypeOptions, fetcherName);

            Assert.Equal(expected, actual);
        }
    }
}
