namespace _2_List_Duplicating_Files
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Security.Cryptography;
    using System.Linq;

    class EntryPoint
    {
        static void Main(string[] args)
        {
            string dirName = @"C:\Users\stefan.sinapov\Documents\Test folder";
            Console.WriteLine("[{0}]", string.Join(", ", ListDuplicatingFiles(dirName)));
        }

        public static IList<string> ListDuplicatingFiles(string dir)
        {
            var allFiles = new List<string>();

            DirSearch(dir, allFiles);

            allFiles = allFiles.Select(f => f.Split('\\').Last()).ToList();

            return allFiles;
        }

        static bool FilesAreEqual(string firstPath, string secondPath)
        {
            var first = new FileInfo(firstPath);
            var second = new FileInfo(secondPath);

            byte[] firstHash = MD5.Create().ComputeHash(first.OpenRead());
            byte[] secondHash = MD5.Create().ComputeHash(second.OpenRead());

            for (int i = 0; i < firstHash.Length; i++)
            {
                if (firstHash[i] != secondHash[i])
                {
                    return false;
                }
            }
            return true;
        }

        static void DirSearch(string dir, ICollection<String> paths)
        {
            try
            {
                foreach (string currentFileName in Directory.GetFiles(dir))
                {
                    bool thereIsEqual = false;
                    foreach (var fileName in paths)
                    {
                        if (FilesAreEqual(fileName, currentFileName))
                        {
                            thereIsEqual = true;
                            break;
                        }
                    }
                    if (!thereIsEqual)
                    {
                        paths.Add(currentFileName);
                    }
                }
                foreach (string innerDir in Directory.GetDirectories(dir))
                {
                    DirSearch(innerDir, paths);
                }

            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}