using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Abstractions;
namespace Quadarax.Foundation.Core.IO.FileSystem.Memory
{
    public class MemoryFileSystem : IFileSystem
    {
        private readonly Dictionary<string, MemoryFileSystemEntry> _fileSystem;

        public MemoryFileSystem()
        {
            _fileSystem = new Dictionary<string, MemoryFileSystemEntry>(StringComparer.OrdinalIgnoreCase);
            File = new MemoryFile(this);
            Directory = new MemoryDirectory(this);
            Path = new MemoryPath(this);
            FileInfo = new MemoryFileInfoFactory(this);
            DirectoryInfo = new MemoryDirectoryInfoFactory(this);
        }

        public IFile File { get; }
        public IDirectory Directory { get; }
        public IPath Path { get; }
        public IFileInfoFactory FileInfo { get; }
        public IDirectoryInfoFactory DirectoryInfo { get; }

        public IDriveInfoFactory DriveInfo => throw new NotImplementedException();

        public IFileStreamFactory FileStream => throw new NotImplementedException();

        public IFileSystemWatcherFactory FileSystemWatcher => throw new NotImplementedException();

        // Implement other properties as needed

        internal Dictionary<string, MemoryFileSystemEntry> FileSystemDictionary => _fileSystem;

        IFileVersionInfoFactory IFileSystem.FileVersionInfo => throw new NotImplementedException();

        internal MemoryFileSystemEntry? ResolveSymbolicLink(MemoryFileSystemEntry entry)
        {
            int maxSymlinkDepth = 40; // Prevent infinite loops
            while (entry.IsSymbolicLink && maxSymlinkDepth > 0)
            {
                if (FileSystemDictionary.TryGetValue(entry.SymbolicLinkTarget, out var targetEntry))
                {
                    entry = targetEntry;
                    maxSymlinkDepth--;
                }
                else
                {
                    // Broken symlink
                    return null;
                }
            }

            if (maxSymlinkDepth == 0)
            {
                throw new IOException("Too many levels of symbolic links");
            }

            return entry;
        }
    }

}