// 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.

#ifndef ZIRCON_SYSTEM_DEV_SYSMEM_SYSMEM_LOGICAL_BUFFER_COLLECTION_H_
#define ZIRCON_SYSTEM_DEV_SYSMEM_SYSMEM_LOGICAL_BUFFER_COLLECTION_H_

#include "device.h"

#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <fuchsia/sysmem/c/fidl.h>
#include <lib/fidl-async-2/fidl_struct.h>
#include <lib/zx/channel.h>

#include <map>
#include <memory>

extern const fidl_type_t fuchsia_sysmem_BufferCollectionConstraintsTable;
extern const fidl_type_t fuchsia_sysmem_ImageFormatConstraintsTable;
extern const fidl_type_t fuchsia_sysmem_BufferCollectionInfo_2Table;

class BufferCollectionToken;
class BufferCollection;
class LogicalBufferCollection
    : public fbl::RefCounted<LogicalBufferCollection> {
public:
    using Constraints =
        FidlStruct<fuchsia_sysmem_BufferCollectionConstraints,
                   &fuchsia_sysmem_BufferCollectionConstraintsTable>;
    using ImageFormatConstraints =
        FidlStruct<fuchsia_sysmem_ImageFormatConstraints,
                   &fuchsia_sysmem_ImageFormatConstraintsTable>;
    using BufferCollectionInfo =
        FidlStruct<fuchsia_sysmem_BufferCollectionInfo_2,
                   &fuchsia_sysmem_BufferCollectionInfo_2Table>;

    ~LogicalBufferCollection();

    static void Create(zx::channel buffer_collection_token_request,
                       Device* parent_device);

    // |parent_device| the Device* that the calling allocator is part of.  The
    // tokens_by_koid_ for each Device is separate.  If somehow two clients were
    // to get connected to two separate sysmem device instances hosted in the
    // same devhost, those clients (intentionally) won't be able to share a
    // LogicalBufferCollection.
    //
    // |buffer_collection_token| the client end of the BufferCollectionToken
    // being turned in by the client to get a BufferCollection in exchange.
    //
    // |buffer_collection_request| the server end of a BufferCollection channel
    // to be served by the LogicalBufferCollection associated with
    // buffer_collection_token.
    static void BindSharedCollection(Device* parent_device,
                                     zx::channel buffer_collection_token,
                                     zx::channel buffer_collection_request);

    // This is used to create the initial BufferCollectionToken, and also used
    // by BufferCollectionToken::Duplicate().
    //
    // The |self| parameter exists only because LogicalBufferCollection can't
    // hold a std::weak_ptr<> to itself because that requires libc++ (the binary
    // not just the headers) which isn't available in Zircon so far.
    void
    CreateBufferCollectionToken(fbl::RefPtr<LogicalBufferCollection> self,
                                uint32_t rights_attenuation_mask,
                                zx::channel buffer_collection_token_request);

    void OnSetConstraints();

    struct AllocationResult {
        const fuchsia_sysmem_BufferCollectionInfo_2* buffer_collection_info =
            nullptr;
        const zx_status_t status = ZX_OK;
    };
    AllocationResult allocation_result();

private:
    LogicalBufferCollection(Device* parent_device);

    void Fail(const char* format, ...);

    static void LogInfo(const char* format, ...);

    static void LogError(const char* format, ...);

    void MaybeAllocate();

    void TryAllocate();

    void SetFailedAllocationResult(zx_status_t status);

    void SetAllocationResult(BufferCollectionInfo info);

    void SendAllocationResult();

    void BindSharedCollectionInternal(BufferCollectionToken* token,
                                      zx::channel buffer_collection_request);

    bool CombineConstraints();

    bool CheckBufferCollectionConstraints(
        const fuchsia_sysmem_BufferCollectionConstraints* constraints);

    bool CheckImageFormatConstraints(
        const fuchsia_sysmem_ImageFormatConstraints* constraints);

    void SanitizeBufferCollectionConstraints(
        fuchsia_sysmem_BufferCollectionConstraints* constraints);

    Constraints BufferCollectionConstraintsClone(
        const fuchsia_sysmem_BufferCollectionConstraints* input);

    ImageFormatConstraints ImageFormatConstraintsClone(
        const fuchsia_sysmem_ImageFormatConstraints* input);

    bool AccumulateConstraintBufferCollection(
        fuchsia_sysmem_BufferCollectionConstraints* acc,
        const fuchsia_sysmem_BufferCollectionConstraints* c);

    bool AccumulateConstraintBufferMemory(
        fuchsia_sysmem_BufferMemoryConstraints* acc,
        const fuchsia_sysmem_BufferMemoryConstraints* c);

    bool AccumulateConstraintImageFormats(
        uint32_t* acc_count, fuchsia_sysmem_ImageFormatConstraints acc[],
        uint32_t c_count, const fuchsia_sysmem_ImageFormatConstraints c[]);

    bool AccumulateConstraintImageFormat(
        fuchsia_sysmem_ImageFormatConstraints* acc,
        const fuchsia_sysmem_ImageFormatConstraints* c);

    bool AccumulateConstraintColorSpaces(uint32_t* acc_count,
                                         fuchsia_sysmem_ColorSpace acc[],
                                         uint32_t c_count,
                                         const fuchsia_sysmem_ColorSpace c[]);

    bool IsColorSpaceEqual(const fuchsia_sysmem_ColorSpace& a,
                           const fuchsia_sysmem_ColorSpace& b);

    BufferCollectionInfo Allocate(zx_status_t* allocation_result);

    zx_status_t AllocateVmo(const fuchsia_sysmem_SingleBufferSettings* settings,
                            zx::vmo* vmo);

    int32_t CompareImageFormatConstraintsTieBreaker(
        const fuchsia_sysmem_ImageFormatConstraints* a,
        const fuchsia_sysmem_ImageFormatConstraints* b);

    int32_t CompareImageFormatConstraintsByIndex(uint32_t index_a,
                                                 uint32_t index_b);

    Device* parent_device_ = nullptr;

    using TokenMap = std::map<BufferCollectionToken*,
                              std::unique_ptr<BufferCollectionToken>>;
    TokenMap token_views_;

    using CollectionMap =
        std::map<BufferCollection*, std::unique_ptr<BufferCollection>>;
    CollectionMap collection_views_;

    bool is_allocate_attempted_ = false;

    Constraints constraints_{Constraints::Null};

    // Iff true, initial allocation has been attempted and has succeeded or
    // failed.  Both allocation_result_status_ and allocation_result_info_ are
    // not meaningful until has_allocation_result_ is true.
    bool has_allocation_result_ = false;
    zx_status_t allocation_result_status_ = ZX_OK;
    BufferCollectionInfo allocation_result_info_{BufferCollectionInfo::Null};
};

#endif // ZIRCON_SYSTEM_DEV_SYSMEM_SYSMEM_LOGICAL_BUFFER_COLLECTION_H_
