// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.io;

using zx;

// TODO: We should run some experiments to see what's the optimum value, or
// what's the point of diminishing marginal returns.
/// The maximum I/O size that is allowed for read/write operations using
/// byte vectors.
const MAX_TRANSFER_SIZE uint64 = 8192;

/// The byte vector type used for read/write operations.
alias Transfer = vector<uint8>:MAX_TRANSFER_SIZE;

/// Denotes which hash algorithm is used to build the merkle tree for
/// fsverity-enabled files.
@available(added=HEAD)
type HashAlgorithm = flexible enum : uint8 {
    SHA256 = 1;
    SHA512 = 2;
};

/// Set of options used to enable verity on a file.
@available(added=HEAD)
type VerificationOptions = table {
    1: hash_algorithm HashAlgorithm;
    /// `salt` is prepended to each block before it is hashed.
    2: salt vector<uint8>:32;
};

/// Auxiliary data for the file representation of a node.
type FileInfo = resource table {
    /// True if the file is opened in append mode.
    /// In append mode, the seek offset is moved to the end before every
    /// write, the two steps performed in an atomic manner.
    1: is_append bool;

    /// An optional event which transmits information about an object's
    /// readability or writability. This event relays information about the
    /// underlying object, not the capability granted to client: this event
    /// may be signalled "readable" on a connection that does not have
    /// the capability to read.
    ///
    /// This event will be present if the following conditions are met:
    ///
    /// - The `available_operations` on the file connection is not empty.
    /// - The filesystem supports signalling readability/writability events.
    ///
    /// The [`FileSignal`] values may be observed on this event.
    2: observer zx.Handle:EVENT;

    /// An optional stream object, which can be used to read to and write from
    /// the file.
    ///
    /// Reading and writing the file using the stream object can be up to 20x
    /// faster than reading and writing the file using the Read and Write
    /// operations in the [`File`] protocol.
    3: stream zx.Handle:STREAM;

    /// Requested attributes for the file. This is only populated if requested.
    @available(added=HEAD)
    4: attributes NodeAttributes2;
};

// TODO(https://fxbug.dev/105608): Use a generated constant.
const FILE_PROTOCOL_NAME string = "fuchsia.io/File";

/// A [`Node`] which contains a sequence of bytes of definite length.
///
/// NOTE: cloned connections do not share their seek offset with their source
/// connection.
closed protocol File {
    compose AdvisoryLocking;
    @available(added=HEAD)
    compose Linkable;
    compose Node;
    compose Readable;
    compose Writable;

    @selector("fuchsia.io/File.Describe")
    strict Describe() -> (FileInfo);

    /// Moves the offset at which the next invocation of [`Read`] or [`Write`]
    /// will occur. The seek offset is specific to each file connection.
    ///
    /// + request `origin` the reference point where `offset` will be based on.
    /// + request `offset` the number of bytes to seek.
    /// - response `offset_from_start` the adjusted seek offset, from the start
    ///   of the file.
    ///
    /// This method does not require any rights.
    @selector("fuchsia.io/File.Seek")
    strict Seek(struct {
        origin SeekOrigin;
        offset int64;
    }) -> (struct {
        offset_from_start uint64;
    }) error zx.Status;

    /// Reads up to 'count' bytes at the provided offset.
    /// Does not affect the seek offset.
    ///
    /// ## Invariants
    ///
    /// * The returned `data.length` will never be greater than `count`.
    /// * If `data.length` is less than `count`, it means that `ReadAt` has hit
    ///   the end of file as part of this operation.
    /// * If `data.length` is zero while `count` is not, it means that `offset`
    ///   is at or past the end of file, and no data can be read.
    /// * If `count` is zero, the server should perform all the checks ensuring
    ///   read access without actually reading anything, and return an empty
    ///   `data` vector.
    ///
    /// This method requires the [`Rights.READ_BYTES`] right.
    ///
    /// Returns `ZX_ERR_OUT_OF_RANGE` if `count` is greater than `MAX_TRANSFER_SIZE`.
    @selector("fuchsia.io/File.ReadAt")
    strict ReadAt(struct {
        count uint64;
        offset uint64;
    }) -> (struct {
        data Transfer;
    }) error zx.Status;

    /// Writes data at the provided offset.
    /// Does not affect the seek offset.
    ///
    /// The file size may grow if `offset` plus `data.length` is past the
    /// current end of file.
    ///
    /// + request `data` the byte buffer to write to the file.
    /// + request `offset` the offset from start of the file to begin writing.
    /// - response `actual_count` the number of bytes written.
    ///
    /// ## Invariants
    ///
    /// * The returned `actual_count` will never be greater than `data.length`.
    /// * If the server is unable to write all the data due to e.g. not enough
    ///   space, `actual_count` may be less than `data.length`.  If no bytes
    ///   could be written, an error is returned.
    /// * If `data.length` is zero, the server should perform all the checks
    ///   ensuring write access without mutating the file, and will return a
    ///   successful write of zero bytes.
    ///
    /// This method requires the [`Rights.WRITE_BYTES`] right.
    @selector("fuchsia.io/File.WriteAt")
    strict WriteAt(struct {
        data Transfer;
        offset uint64;
    }) -> (struct {
        actual_count uint64;
    }) error zx.Status;

    /// Shrinks or grows the file size to 'length' bytes.
    ///
    /// If file size is reduced by this operation, the extra trailing data'
    /// is discarded.
    /// If file size is increased by this operation, the extended area appears
    /// as if it was zeroed.
    ///
    /// This method requires the [`Rights.WRITE_BYTES`] right.
    @selector("fuchsia.io/File.Resize")
    strict Resize(struct {
        length uint64;
    }) -> () error zx.Status;

    /// Acquires a [`zx.Handle:VMO`] representing this file, if there is one,
    /// with the requested access rights.
    ///
    /// Implementations are not required to implement files backed by VMOs so
    /// this request may fail. Additionally, implementations may only support
    /// a certain subset of the flags. Clients should be prepared with fallback
    /// behavior if this request fails.
    ///
    /// If a client specifies neither `PRIVATE_CLONE` nor `SHARED_BUFFER`, the
    /// implementation is free to choose the semantics of the returned VMO.
    ///
    /// + request `flags` a [`VmoFlags`] indicating the desired mode of access.
    /// - response `vmo` the requested [`zx.Handle:VMO`].
    /// * error a [`zx.Status`] value indicating the failure.
    ///
    /// This method requires the following rights:
    ///
    /// * [`Rights.READ_BYTES`] if `flags` includes [`VmoFlags.READ`].
    /// * [`Rights.WRITE_BYTES`] if `flags` includes [`VmoFlags.WRITE`].
    /// * [`Rights.EXECUTE`] if `flags` includes [`VmoFlags.EXECUTE`].
    @selector("fuchsia.io/File.GetBackingMemory")
    strict GetBackingMemory(struct {
        flags @generated_name("VmoFlags") strict bits : uint32 {
            /// Requests that the VMO be readable.
            READ = 0x00000001;

            /// Requests that the VMO be writable.
            WRITE = 0x00000002;

            /// Request that the VMO be executable.
            EXECUTE = 0x00000004;

            /// Require a copy-on-write clone of the underlying VMO. The request
            /// should fail if the VMO cannot be cloned. May not be supplied
            /// with `SHARED_BUFFER`.
            ///
            /// A private clone uses at least the guarantees of the
            /// `ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE` flag to
            /// `zx_vmo_create_child()`. This means that the returned VMO will
            /// be copy-on-write (if `WRITE` is requested) but that it may or
            /// may not reflect subsequent content changes to the underlying
            /// file. The returned VMO will not reflect size changes to the
            /// file. These semantics match those of the POSIX `mmap()`
            /// `MAP_PRIVATE` flag.
            ///
            /// In some cases, clients requiring a guaranteed snapshot of the
            /// file can use `SHARED_BUFFER` and then use
            /// `zx_vmo_create_child()` with `ZX_VMO_CHILD_SNAPSHOT`. However,
            /// in addition to cases where the implementation can't return a
            /// `SHARED_BUFFER`, creating a full snapshot will fail if the VMO
            /// is attached to the pager. Since most filesystems will use the
            /// paging system, the full snapshot approach should only be used in
            /// specific cases where the client is talking to a known server.
            PRIVATE_CLONE = 0x00010000;

            /// Require a VMO that provides direct access to the contents of the
            /// file's underlying VMO. The request should fail if such a VMO
            /// cannot be provided. May not be supplied with `PRIVATE_CLONE`.
            ///
            /// The returned VMO may not be resizable even when `WRITE` access is
            /// requested. In this case, [`File.Resize`] should be used to resize
            /// the file.
            SHARED_BUFFER = 0x00020000;
        };
    }) -> (resource struct {
        vmo zx.Handle:VMO;
    }) error zx.Status;

    /// Pre-allocate on-disk space for this file.
    @available(added=HEAD)
    @selector("fuchsia.io/File.Allocate")
    strict Allocate(resource struct {
        offset uint64;
        length uint64;

        /// If an empty bits is passed for mode, the default behavior is used. Otherwise the
        /// behavior is modified as described for each mode bit. If the backing filesystem doesn't
        /// support a particular provided mode bit, or combination of mode bits, an error is
        /// returned.
        mode @generated_name("AllocateMode") flexible bits : uint32 {
            KEEP_SIZE = 0x00000001;
            UNSHARE_RANGE = 0x00000002;
            PUNCH_HOLE = 0x00000004;
            COLLAPSE_RANGE = 0x00000008;
            ZERO_RANGE = 0x00000010;
            INSERT_RANGE = 0x00000020;
        };
    }) -> () error zx.Status;

    /// Enables verification for the file (permanently) which involves computing a merkle tree for
    /// the file. Forces a flush prior to building the merkle tree to ensure cached data is
    /// captured. Future reads will be verified against the computed merkle tree and writes will be
    /// rejected. This method can take some time to complete as it depends on the size of the file.
    /// This method can be aborted by closing the connection that this method was issued on.
    ///
    /// This method requires the [`Rights.UPDATE_ATTRIBUTES`] right.
    /// Returns `ZX_ERR_NOT_SUPPORTED` if the filesystem does not support verity.
    /// Returns `ZX_ERR_ALREADY_EXISTS` if the file was already fsverity-enabled.
    /// Also returns any error that might arise from reading the file, or from flushing the file,
    /// such as `ZX_ERR_IO`.
    @selector("fuchsia.io/File.EnableVerity")
    @available(added=HEAD)
    strict EnableVerity(resource struct {
        options VerificationOptions;
    }) -> () error zx.Status;
};

closed protocol Readable {
    /// Reads up to 'count' bytes at the seek offset.
    /// The seek offset is moved forward by the number of bytes read.
    ///
    /// ## Invariants
    ///
    /// * The returned `data.length` will never be greater than `count`.
    /// * If `data.length` is less than `count`, it means that the seek offset
    ///   has reached the end of file as part of this operation.
    /// * If `data.length` is zero while `count` is not, it means that the
    ///   seek offset is already at or beyond the end of file, and no data could
    ///   be read.
    /// * If `count` is zero, the server should perform all the checks ensuring
    ///   read access without actually read anything, and return an empty
    ///   `data` vector.
    ///
    /// This method requires the [`Rights.READ_BYTES`] right.
    ///
    /// Returns `ZX_ERR_OUT_OF_RANGE` if `count` is greater than `MAX_TRANSFER_SIZE`.
    @selector("fuchsia.io/File.Read")
    strict Read(struct {
        count uint64;
    }) -> (struct {
        data Transfer;
    }) error zx.Status;
};

closed protocol Writable {
    /// Writes data at the seek offset.
    /// The seek offset is moved forward by the number of bytes written.
    /// If the file is in append mode, the seek offset is first set to the end
    /// of the file, followed by the write, in one atomic step.
    ///
    /// The file size may grow if the seek offset plus `data.length` is beyond
    /// the current end of file.
    ///
    /// + request `data` the byte buffer to write to the file.
    /// - response `actual_count` the number of bytes written.
    ///
    /// ## Invariants
    ///
    /// * The returned `actual_count` will never be greater than `data.length`.
    /// * If the server is unable to write all the data due to e.g. not enough
    ///   space, `actual_count` may be less than `data.length`.  If no bytes
    ///   could be written, an error is returned.
    /// * If `data.length` is zero, the server should perform all the checks
    ///   ensuring write access without mutating the file and return a
    ///   successful write of zero bytes.  The seek offset is still updated if
    ///   in append mode.
    ///
    /// This method requires the [`Rights.WRITE_BYTES`] right.
    @selector("fuchsia.io/File.Write")
    strict Write(struct {
        data Transfer;
    }) -> (struct {
        actual_count uint64;
    }) error zx.Status;
};

/// The reference point for updating the seek offset. See [`File.Seek`].
///
/// This enum matches the `zx_stream_seek_origin_t` enum.
type SeekOrigin = strict enum : uint32 {
    /// Seek from the start of the file.
    /// The seek offset will be set to `offset` bytes.
    /// The seek offset cannot be negative in this case.
    START = 0;

    /// Seek from the current position in the file.
    /// The seek offset will be the current seek offset plus `offset` bytes.
    CURRENT = 1;

    /// Seek from the end of the file.
    /// The seek offset will be the file size plus `offset` bytes.
    END = 2;
};

type FileSignal = strict bits : uint32 {
    /// Indicates the file is ready for reading.
    READABLE = 0x01000000; // ZX_USER_SIGNAL_0

    /// Indicates the file is ready for writing.
    WRITABLE = 0x02000000; // ZX_USER_SIGNAL_1
};
