using System.Collections.Generic;
using System.Threading.Tasks;

namespace AIRuntime.Runtime.Filesystem
{
    /// <summary>
    /// Abstraction over a filesystem implementation.
    /// Capabilities should only interact with this interface,
    /// never directly with System.IO.
    /// </summary>
    public interface IFileSystem
    {
        // --------------------------------------------------
        // File Operations
        // --------------------------------------------------
        Task ValidatePathAsync(string path);
        Task<bool> FileExistsAsync(string path);

        Task<string> ReadFileAsync(string path);

        Task WriteFileAsync(string path, string contents);

        Task AppendFileAsync(string path, string contents);

        Task DeleteFileAsync(string path);

        Task MoveFileAsync(string source, string destination);

        Task CopyFileAsync(string source, string destination);

        // --------------------------------------------------
        // Directory Operations
        // --------------------------------------------------

        Task<bool> DirectoryExistsAsync(string path);

        Task CreateDirectoryAsync(string path);

        Task DeleteDirectoryAsync(string path, bool recursive);

        Task<IReadOnlyList<string>> ListDirectoryAsync(string path);

        // --------------------------------------------------
        // Information
        // --------------------------------------------------

        Task<FileInfoModel> GetFileInfoAsync(string path);
    }


    /// <summary>
    /// Optional stronger filesystem contract for optimistic concurrency and
    /// same-directory atomic replacement. Capability code falls back to the
    /// legacy interface for custom filesystems that have not adopted it.
    /// </summary>
    public interface IAtomicFileSystem
    {
        Task<AtomicFileWriteResult> WriteFileAtomicallyAsync(
            string path,
            string contents,
            string expectedSha256,
            bool expectedAbsent,
            bool allowOverwrite);
    }


    public sealed class AtomicFileWriteResult
    {
        public bool Created { get; set; }
        public bool Replaced { get; set; }
        public string PreviousSha256 { get; set; }
        public string CurrentSha256 { get; set; }
        public long PreviousLength { get; set; }
        public long CurrentLength { get; set; }
    }
}
