using TeleWave.Application.Media.MovieImport;
using Xunit;

namespace TeleWave.Application.Tests.Media;

/// <summary>
/// Разбор имён релизов. Набор — реальные имена из библиотеки пользователя: парсер, проверенный
/// на выдуманных примерах, разбирает выдуманные имена, а не те, что лежат в каталоге.
/// </summary>
public class MovieNameParserTests
{
    [Theory]
    // Год в скобках вместе с качеством — самый частый вид.
    [InlineData("Die Hard 2 [1990 HDRip].avi", "Die Hard 2", 1990)]
    [InlineData("Face Off [1997 BDRip].avi", "Face Off", 1997)]
    [InlineData("Terminator (1984) Scan 35mm.mkv", "Terminator", 1984)]
    // Точки вместо пробелов — вид с трекеров.
    [InlineData("Voron.1994.TRIPLE.BDRip.XviD.AC3.avi", "Voron", 1994)]
    [InlineData("Green.Mile.1999.bdrip-avc.dexter.mkv", "Green Mile", 1999)]
    [InlineData("Gladiator.2000.Extended.DUB.Hybrid.mkv", "Gladiator", 2000)]
    [InlineData("Bolshoi.Lebovski.1998.DUAL.BDRip", "Bolshoi Lebovski", 1998)]
    [InlineData("Osnovnoi.Instinkt.1992.TRIPLE.BDRip.mkv", "Osnovnoi Instinkt", 1992)]
    [InlineData("Shou.Trumana.1998.BDRip.AVC.mkv", "Shou Trumana", 1998)]
    [InlineData("Pyatyi.Element.1997.BDRip.avi", "Pyatyi Element", 1997)]
    [InlineData("Molchanie.yagnyat.1991.BDRip.avi", "Molchanie yagnyat", 1991)]
    [InlineData("Liudi.V.Chernom.II.2002.BDRip-AVC.mkv", "Liudi V Chernom II", 2002)]
    [InlineData("Double Trouble.1992.TRIPLERUS.BDRip.avi", "Double Trouble", 1992)]
    // Подчёркивания и скобки с пометкой издания.
    [InlineData("Forrest_Gump_1994_BDRip-AVC_b.mkv", "Forrest Gump", 1994)]
    [InlineData("Unbreakable_2000_BDRip_[REMASTERED]", "Unbreakable", 2000)]
    // Апостроф в названии переживает разбор.
    [InlineData("Knockin' On Heaven's Door.1997.BDRip.mkv", "Knockin' On Heaven's Door", 1997)]
    public void Parse_TakesTitleAndYear(string name, string title, int year)
    {
        var parsed = MovieNameParser.Parse(name);

        Assert.Equal(title, parsed.Title);
        Assert.Equal(year, parsed.Year);
    }

    [Theory]
    // Года нет — название обрывается на первом техническом маркере.
    [InlineData("Pulp.Fiction.HDRip.Kubik.v.Kube.mkv", "Pulp Fiction")]
    [InlineData("From.Dusk.Till.Dawn.HDRip.Kubik.mkv", "From Dusk Till Dawn")]
    [InlineData("Die Hard.mkv", "Die Hard")]
    [InlineData("Temple.of.Doom.mkv", "Temple of Doom")]
    [InlineData("Lock.Stock.and.Two.Smoking.Barrels.mkv", "Lock Stock and Two Smoking Barrels")]
    public void Parse_WithoutYear_CutsAtReleaseMarker(string name, string title)
    {
        var parsed = MovieNameParser.Parse(name);

        Assert.Equal(title, parsed.Title);
        Assert.Null(parsed.Year);
    }

    [Fact]
    public void Parse_DropsReleaserNickname_AndDoesNotTakeYearFromIt()
    {
        // Ник релизера идёт после «by», и год внутри него — не год выпуска.
        var parsed = MovieNameParser.Parse("Edward Scissorhands by_IVAN@1990.mkv");

        Assert.Equal("Edward Scissorhands", parsed.Title);
        Assert.Null(parsed.Year);
    }

    [Fact]
    public void Parse_KeepsNumericTitle()
    {
        // «2012» — это название, а не год: год берётся только со второго вхождения.
        var parsed = MovieNameParser.Parse("2012.2009.BDRip.XviD.mkv");

        Assert.Equal("2012", parsed.Title);
        Assert.Equal(2009, parsed.Year);
    }

    [Fact]
    public void Parse_KeepsFolderNameWhole_WhenTailLooksLikeExtension()
    {
        // У папки релиза «расширением» выглядит последняя часть имени, и отрезать её нельзя.
        var parsed = MovieNameParser.Parse("Voron.1994.TRIPLE.BDRip.XviD.AC3");

        Assert.Equal("Voron", parsed.Title);
        Assert.Equal(1994, parsed.Year);
    }

    [Fact]
    public void Parse_LeavesUnrecognizedNameAsIs()
    {
        // Ни года, ни маркеров: разбирать нечего, и подсовывать обрезок хуже, чем показать имя
        // целиком — правит его всё равно человек.
        var parsed = MovieNameParser.Parse("Back to the Future - Part II - More.mkv");

        Assert.Equal("Back to the Future - Part II - More", parsed.Title);
        Assert.Null(parsed.Year);
    }

    [Fact]
    public void Parse_EmptyName_IsEmpty()
    {
        var parsed = MovieNameParser.Parse("   ");

        Assert.Equal(string.Empty, parsed.Title);
        Assert.Null(parsed.Year);
    }
}
