@0x8c2f829df1930cd5;

using CSharp = import "programming_language/csharp.capnp";
$CSharp.namespace("FabAccessAPI.Schema");

using import "notify.capnp".Notifiable;
using import "interest.capnp".Interestable;
using import "interest.capnp".Interest;
using import "claim.capnp".Claimable;
using import "claim.capnp".Claim;
using import "claim.capnp".Lockable;
using import "claim.capnp".Lock;
using import "audit.capnp".Auditable;

using import "utils.capnp".OID;
using import "utils.capnp".L10NString;
using import "utils.capnp".Map;

using import "traits.capnp".Hint;

using import "cache.capnp".Cache;

struct RestoredResource {
    resource @0 :Resource;
    interest @1 :List(Interest);
    claim @2 :Claim;
    lock @3 :Lock;
}

struct Resource {
    # BFFH's smallest unit of a physical or abstract "thing".  A resource can be as simple and
    # physical as a table, as complex as a PCB production line or as abstract as "people with
    # specific know-how are present".

    identifier @0 :Text;
    # The unique identifier for this resource

    description @1 :Cache(Description);
    # Return information about this resource.  This information is usually
    # static and thus put behind a Cache.

    notify @2 :Notifiable;
    # NULL if the user does not have permission to read this resource, or if this resource is not
    # notifiable

    interest @3 :Interestable;
    # NULL if this resource is not interestable or the user does not have permission to set
    # interests for this resource.

    claim @4 :Claimable;
    # NULL if the user does not have permission to write to this resource, or if this resource type
    # does not support claiming.

    lock @5 :Lockable;
    # NULL if the user does not have permission to manage this resource, or if this resource type
    # does not support claiming or locking.

    audit @6 :Auditable;

    hint @7 :Hint;
}

struct Description {
    name @0 :L10NString;
    # A human-facing name for this resource.  A name should be short and recognizable, and is meant
    # as the primary identifier for users to find a resource.

    description @1 :L10NString;
    # A human-facing description for this resource.  Descriptions are longer-form text that give
    # additional information about a resource beyond a name.  They are meant to provide either
    # further identifying information or important information that users should be actively shown
    # when selecting this resource.

    types @2 :List(OID);
    # The 'type' of Resource.  Each OID in the list specifies certain behaviours that this Resource
    # follows.

    category @3 :Category;
    # A category this resource belongs to. If a resource was not assigned a category this is empty,
    # see the definition of [`Category`](struct::Category) for details.

    metadata @4 :Map(Text, Metadata);
    # Metadata associated with this resource.  This can be things like links to wikis or similar.
    # Common keys are pre-defined as constants in this file.
}

struct Metadata {
    # Metadata associated with a specific resource description.

    union {
        inline :group {
            mediaType @0 :Text;  # Media type of the value sent (as per https://www.iana.org/assignments/media-types/media-types.xhtml )
            value @1 :Data;     # The value as BLOB
        }

        remoteInline @2 :Text;
        # URL pointing to the value. A client should fetch it and show it inline

        remoteUrl @3 :Text;
        # An URL that *is* the value. A client should display this as a clickable link.
    }
}

struct Category {
    # A category this resource belongs to.

    id @0 :Data;
    # An unique ID for this category.  If a resource was not assigned a category this is NULL.

    name @1 :L10NString;
    # A human-facing name for this category.
}

const metadataWiki :Text = "wiki";
# An URI to further detailed information about this resource, e.g. in a wiki.  This SHOULD be an
# https URL.