context: using System.Collections.Generic;
  using System.IO;
  using System.Linq;
  using FizzWare.NBuilder;
  using Moq;
  using NUnit.Framework;
  using NzbDrone.Common.Disk;
  using NzbDrone.Common.Extensions;
  using NzbDrone.Core.Configuration;
  using NzbDrone.Core.MediaFiles;
  using NzbDrone.Core.MediaFiles.MovieImport;
  using NzbDrone.Core.Movies;
  using NzbDrone.Core.RootFolders;
  using NzbDrone.Core.Test.Framework;
  using NzbDrone.Test.Common;
  
  namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
  {
      [TestFixture]
      public class ScanFixture : CoreTest<DiskScanService>
      {
          private Movie _movie;
          private string _rootFolder;
          private string _otherMovieFolder;
  
          [SetUp]
          public void Setup()
          {
              _rootFolder = @"C:\Test\Movies".AsOsAgnostic();
              _otherMovieFolder = @"C:\Test\Movies\OtherMovie".AsOsAgnostic();
              var movieFolder = @"C:\Test\Movies\Movie".AsOsAgnostic();
  
              _movie = Builder<Movie>.CreateNew()
                  .With(s => s.Path = movieFolder)
                                       .Build();
  
              Mocker.GetMock<IDiskProvider>()
                    .Setup(s => s.FolderExists(It.IsAny<string>()))
                    .Returns(false);
  
              Mocker.GetMock<IDiskProvider>()
                    .Setup(s => s.GetParentFolder(It.IsAny<string>()))
                    .Returns((string path) => Directory.GetParent(path).FullName);
  
              Mocker.GetMock<IRootFolderService>()
                    .Setup(s => s.GetBestRootFolderPath(It.IsAny<string>()))
                    .Returns(_rootFolder);
  
              Mocker.GetMock<IMediaFileService>()
                    .Setup(s => s.GetFilesByMovie(It.IsAny<int>()))
                    .Returns(new List<MovieFile>());
          }
  
          private void GivenRootFolder(params string[] subfolders)
          {
              Mocker.GetMock<IDiskProvider>()
                  .Setup(s => s.FolderExists(_rootFolder))
                    .Returns(true);
  
              Mocker.GetMock<IDiskProvider>()
                    .Setup(s => s.GetDirectories(_rootFolder))
                    .Returns(subfolders);
  
              Mocker.GetMock<IDiskProvider>()
                    .Setup(s => s.FolderEmpty(_rootFolder))
                    .Returns(subfolders.Empty());
  
              foreach (var folder in subfolders)
              {
                  Mocker.GetMock<IDiskProvider>()
                    .Setup(s => s.FolderExists(folder))
                    .Returns(true);
              }
          }
  
          private void GivenMovieFolder()
          {
              GivenRootFolder(_movie.Path);
          }
  
          private void GivenFiles(IEnumerable<string> files)
          {
              Mocker.GetMock<IDiskProvider>()
                    .Setup(s => s.GetFiles(It.IsAny<string>(), SearchOption.AllDirectories))
                    .Returns(files.ToArray());
          }
  
          [Test]
          public void should_not_scan_if_movie_root_folder_does_not_exist()
          {
              Subject.Scan(_movie);
  
              ExceptionVerification.ExpectedWarns(1);
  
              Mocker.GetMock<IDiskProvider>()
                    .Verify(v => v.GetFiles(_movie.Path, SearchOption.AllDirectories), Times.Never());
  
              Mocker.GetMock<IDiskProvider>()
                    .Verify(v => v.CreateFolder(_movie.Path), Times.Never());
  
              Mocker.GetMock<IMediaFileTableCleanupService>()
                  .Verify(v => v.Clean(It.IsAny<Movie>(), It.IsAny<List<string>>()), Times.Never());
          }
  
          [Test]
          public void should_not_scan_if_movie_root_folder_is_empty()
          {
              GivenRootFolder();
  
              Subject.Scan(_movie);
  
              ExceptionVerification.ExpectedWarns(1);
  
              Mocker.GetMock<IDiskProvider>()
                    .Verify(v => v.GetFiles(_movie.Path, SearchOption.AllDirectories), Times.Never());
  
              Mocker.GetMock<IDiskProvider>()
                    .Verify(v => v.CreateFolder(_movie.Path), Times.Never());
  
              Mocker.GetMock<IMediaFileTableCleanupService>()
                    .Verify(v => v.Clean(It.IsAny<Movie>(), It.IsAny<List<string>>()), Times.Never());
  
              Mocker.GetMock<IMakeImportDecision>()
                    .Verify(v => v.GetImportDecisions(It.IsAny<List<string>>(), _movie, false), Times.Never());
          }
  
          [Test]
          public void should_create_if_movie_folder_does_not_exist_but_create_folder_enabled()
          {
              GivenRootFolder(_otherMovieFolder);
  
              Mocker.GetMock<IConfigService>()
                    .Setup(s => s.CreateEmptyMovieFolders)
                    .Returns(true);
  
              Subject.Scan(_movie);
  
              Mocker.GetMock<IDiskProvider>()
                    .Verify(v => v.CreateFolder(_movie.Path), Times.Once());
          }
  
          [Test]
          public void should_not_scan_extras_subfolder()
          {
              GivenMovieFolder();
  
              GivenFiles(new List<string>
                         {
                             Path.Combine(_movie.Path, "EXTRAS", "file1.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Extras", "file2.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "EXTRAs", "file3.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "ExTrAs", "file4.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Season 1", "s01e01.mkv").AsOsAgnostic()
                         });
  
              Subject.Scan(_movie);
  
              Mocker.GetMock<IMakeImportDecision>()
                    .Verify(v => v.GetImportDecisions(It.Is<List<string>>(l => l.Count == 1), _movie, false), Times.Once());
          }
  
          [Test]
          public void should_not_scan_various_extras_subfolders()
          {
              GivenMovieFolder();
  
              GivenFiles(new List<string>
                         {
                             Path.Combine(_movie.Path, "Behind the Scenes", "file1.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Deleted Scenes", "file2.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Featurettes", "file3.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Interviews", "file4.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Sample", "file5.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Samples", "file6.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Scenes", "file7.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Shorts", "file8.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Trailers", "file9.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "The Count of Monte Cristo (2002) (1080p BluRay x265 10bit Tigole).mkv").AsOsAgnostic(),
                         });
  
              Subject.Scan(_movie);
  
              Mocker.GetMock<IMakeImportDecision>()
                    .Verify(v => v.GetImportDecisions(It.Is<List<string>>(l => l.Count == 1), _movie, false), Times.Once());
          }
  
          [Test]
          public void should_not_scan_featurettes_subfolders()
          {
              GivenMovieFolder();
  
              GivenFiles(new List<string>
                         {
                             Path.Combine(_movie.Path, "Featurettes", "An Epic Reborn.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Featurettes", "Deleted & Alternate Scenes.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Featurettes", "En Garde - Multi-Angle Dailies.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "Featurettes", "Layer-By-Layer - Sound Design - Multiple Audio.mkv").AsOsAgnostic(),
                             Path.Combine(_movie.Path, "The Count of Monte Cristo (2002) (1080p BluRay x265 10bit Tigole).mkv").AsOsAgnostic(),
                         });
  
              Subject.Scan(_movie);
  
              Mocker.GetMock<IMakeImportDecision>()
                    .Verify(v => v.GetImportDecisions(It.Is<List<string>>(l => l.Count == 1), _movie, false), Times.Once());
          }
  
          [Test]
          public void should_not_create_if_movie_folder_does_not_exist_and_create_folder_disabled()
          {
              GivenRootFolder(_otherMovieFolder);
  
              Mocker.GetMock<IConfigService>()
  
gt:                   .Setup(s => s.CreateEmptyMovieFolders)