// Copyright 2022 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.sysmem2.internal;

using fuchsia.sysmem;
using fuchsia.sysmem2;
using zx;

// Sysmem serves CombinedBufferCollectionToken to back both
// fuchsia.sysmem.BufferCollectionToken and
// fuchsia.sysmem2.BufferCollectionToken.  We do this to keep the sysmem(1) and
// sysmem2 token client interfaces separate, while also avoiding any need for
// pointless token conversion messages / channel replacements.
//
// This applies to sysmem(1) and sysmem2 tokens (from a client's point of view).
// We may revisit how we do this if we end up adding a third token protocol that
// has stateful aspects that differ more from how sysmem(1) and sysmem2 tokens
// work (for example).
//
// It might be nice if there were a way in FIDL to compose two protocols with
// same-named messages, but (understandably) that's not presently supported in
// any way (that I know of) other than the message-by-message way below.  The
// logical intent here is this (with fictitious attribute to (pretend to) avoid
// the name conflicts that occur if one actually tries to fidlgen this):
//
// protocol CombinedBufferCollectionToken {
//    @message-name-disambiguator(prefix="", suffix="V1")
//    compose fuchsia.sysmem.BufferCollectionToken;
//    @message-name-disambiguator(prefix="", suffix="V2")
//    compose fuchsia.sysmem2.BufferCollectionToken;
//};
//
// Instead, we'll keep this in sync manually (at least for now):

const MAX_COUNT_DUPLICATES_V1 uint32 = 64;
const MAX_COUNT_DUPLICATES_V2 uint32 = 64;

open protocol CombinedBufferCollectionToken {
    // fuchsia.sysmem/Node, with de-conflicted names:
    @selector("fuchsia.sysmem/Node.Sync")
    strict SyncV1() -> ();
    @selector("fuchsia.sysmem/Node.Close")
    strict CloseV1();
    @selector("fuchsia.sysmem/Node.SetName")
    strict SetNameV1(struct {
        priority uint32;
        name string:64;
    });
    @selector("fuchsia.sysmem/Node.SetDebugClientInfo")
    strict SetDebugClientInfoV1(struct {
        name string:64;
        id uint64;
    });
    @selector("fuchsia.sysmem/Node.SetDebugTimeoutLogDeadline")
    strict SetDebugTimeoutLogDeadlineV1(struct {
        deadline zx.Time;
    });
    @selector("fuchsia.sysmem/Node.SetVerboseLogging")
    strict SetVerboseLoggingV1();
    @selector("fuchsia.sysmem/Node.GetNodeRef")
    strict GetNodeRefV1() -> (resource struct {
        node_ref zx.Handle:EVENT;
    });
    @selector("fuchsia.sysmem/Node.IsAlternateFor")
    strict IsAlternateForV1(resource struct {
        node_ref zx.Handle:EVENT;
    }) -> (struct {
        is_alternate bool;
    }) error zx.Status;

    @selector("fuchsia.sysmem/BufferCollectionToken.DuplicateSync")
    strict DuplicateSyncV1(struct {
        rights_attenuation_masks vector<zx.Rights>:MAX_COUNT_DUPLICATES_V1;
    }) -> (resource struct {
        tokens vector<client_end:fuchsia.sysmem.BufferCollectionToken>:MAX_COUNT_DUPLICATES_V1;
    });
    @selector("fuchsia.sysmem/BufferCollectionToken.Duplicate")
    strict DuplicateV1(resource struct {
        rights_attenuation_mask uint32;
        token_request server_end:fuchsia.sysmem.BufferCollectionToken;
    });
    @selector("fuchsia.sysmem/BufferCollectionToken.SetDispensable")
    strict SetDispensableV1();
    @selector("fuchsia.sysmem/BufferCollectionToken.CreateBufferCollectionTokenGroup")
    strict CreateBufferCollectionTokenGroupV1(resource struct {
        group_request server_end:fuchsia.sysmem.BufferCollectionTokenGroup;
    });

    // fuchsia.sysmem2/Node, with de-conflicted names:
    @selector("fuchsia.sysmem2/Node.Sync")
    flexible SyncV2() -> ();
    @selector("fuchsia.sysmem2/Node.Release")
    flexible ReleaseV2();
    @selector("fuchsia.sysmem2/Node.SetName")
    flexible SetNameV2(table {
        1: priority uint32;
        2: name string:64;
    });
    @selector("fuchsia.sysmem2/Node.SetDebugClientInfo")
    flexible SetDebugClientInfoV2(table {
        1: name string:fuchsia.sysmem2.MAX_CLIENT_NAME_LENGTH;
        2: id uint64;
    });
    @selector("fuchsia.sysmem2/Node.SetDebugTimeoutLogDeadline")
    flexible SetDebugTimeoutLogDeadlineV2(table {
        1: deadline zx.Time;
    });
    @selector("fuchsia.sysmem2/Node.SetVerboseLogging")
    flexible SetVerboseLoggingV2();
    @selector("fuchsia.sysmem2/Node.GetNodeRef")
    flexible GetNodeRefV2() -> (resource table {
        1: node_ref zx.Handle:EVENT;
    });
    @selector("fuchsia.sysmem2/Node.IsAlternateFor")
    flexible IsAlternateForV2(resource table {
        1: node_ref zx.Handle:EVENT;
    }) -> (table {
        1: is_alternate bool;
    }) error zx.Status;
    @selector("fuchsia.sysmem2/Node.GetBufferCollectionId")
    flexible GetBufferCollectionIdV2() -> (table {
        1: buffer_collection_id uint64;
    });
    @selector("fuchsia.sysmem2/Node.SetWeak")
    flexible SetWeakV2();
    @selector("fuchsia.sysmem2/Node.SetWeakOk")
    flexible SetWeakOkV2(resource table {
        1: for_child_nodes_also bool;
    });

    // fuchsia.sysmem2/BufferCollectionToken, with de-conflicted names:
    @selector("fuchsia.sysmem2/BufferCollectionToken.DuplicateSync")
    flexible DuplicateSyncV2(table {
        1: rights_attenuation_masks vector<zx.Rights>:MAX_COUNT_DUPLICATES_V2;
    }) -> (resource table {
        1: tokens vector<client_end:fuchsia.sysmem2.BufferCollectionToken>:MAX_COUNT_DUPLICATES_V2;
    });
    @selector("fuchsia.sysmem2/BufferCollectionToken.Duplicate")
    flexible DuplicateV2(resource table {
        1: rights_attenuation_mask zx.Rights;
        2: token_request server_end:fuchsia.sysmem2.BufferCollectionToken;
    });
    @selector("fuchsia.sysmem2/BufferCollectionToken.SetDispensable")
    flexible SetDispensableV2();
    @selector("fuchsia.sysmem2/BufferCollectionToken.CreateBufferCollectionTokenGroup")
    flexible CreateBufferCollectionTokenGroupV2(resource table {
        1: group_request server_end:fuchsia.sysmem2.BufferCollectionTokenGroup;
    });
};

// For BufferCollection and BufferCollectionTokenGroup, we don't do a combined server.  For some
// templates we use this stand-in to avoid extra template specializations where they're not really
// needed. This is not part of the API or SDK, it just creates some helpful generated code.
open protocol EmptyCombinedServerEnd {};
