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

#pragma once

#include <ddk/protocol/platform/proxy.h>
#include <ddktl/device.h>
#include <fbl/intrusive_wavl_tree.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <fbl/unique_ptr.h>
#include <fbl/vector.h>
#include <lib/zx/channel.h>

#include "platform-proxy-device.h"
#include "proxy-protocol.h"

namespace platform_bus {

class ProxyDevice;

class PlatformProxy;
using PlatformProxyType = ddk::Device<PlatformProxy>;

// This is the main class for the proxy side platform bus driver.
// It handles RPC communication with the main platform bus driver in the root devhost.
// It also manages a collection of protocol clients for vendor or SOC-specific protocols.
// In the case where these protocols exist, this class loads the protocol client drivers
// before starting the platform device driver.
class PlatformProxy : public PlatformProxyType, public fbl::RefCounted<PlatformProxy> {
public:
    static zx_status_t Create(zx_device_t* parent, zx_handle_t rpc_channel);

    // Device protocol implementation.
    void DdkRelease();

    zx_status_t Rpc(uint32_t device_id, const platform_proxy_req_t* req, size_t req_length,
                    platform_proxy_rsp_t* resp, size_t resp_length, const zx_handle_t* in_handles,
                    size_t in_handle_count, zx_handle_t* out_handles, size_t out_handle_count,
                    size_t* out_actual);

    inline zx_status_t Rpc(uint32_t device_id, const platform_proxy_req_t* req, size_t req_length,
                           platform_proxy_rsp_t* resp, size_t resp_length) {
        return Rpc(device_id, req, req_length, resp, resp_length, nullptr, 0, nullptr, 0, nullptr);
    }

    zx_status_t GetProtocol(uint32_t proto_id, void* out);
    zx_status_t RegisterProtocol(uint32_t proto_id, const void* protocol);
    void UnregisterProtocol(uint32_t proto_id);
    zx_status_t Proxy(
         const void* req_buffer, size_t req_size, const zx_handle_t* req_handle_list,
         size_t req_handle_count, void* out_resp_buffer, size_t resp_size, size_t* out_resp_actual,
         zx_handle_t* out_resp_handle_list, size_t resp_handle_count,
         size_t* out_resp_handle_actual);

private:
    // This class is a wrapper for a protocol added via platform_proxy_register_protocol().
    // It also is the element type for the protocols_ WAVL tree.
    class PlatformProtocol : public fbl::WAVLTreeContainable<fbl::unique_ptr<PlatformProtocol>> {
    public:
        PlatformProtocol(uint32_t proto_id, const ddk::AnyProtocol* protocol)
            : proto_id_(proto_id), protocol_(*protocol) {}

        inline uint32_t GetKey() const { return proto_id_; }
        inline void GetProtocol(void* out) const { memcpy(out, &protocol_, sizeof(protocol_)); }

    private:
        const uint32_t proto_id_;
        ddk::AnyProtocol protocol_;
    };

    friend class fbl::RefPtr<PlatformProxy>;
    friend class fbl::internal::MakeRefCountedHelper<PlatformProxy>;

    explicit PlatformProxy(zx_device_t* parent, zx_handle_t rpc_channel)
        :  PlatformProxyType(parent), rpc_channel_(rpc_channel) {}

    DISALLOW_COPY_ASSIGN_AND_MOVE(PlatformProxy);

    zx_status_t Init(zx_device_t* parent);

    const zx::channel rpc_channel_;
    fbl::WAVLTree<uint32_t, fbl::unique_ptr<PlatformProtocol>> protocols_;
    uint32_t protocol_count_;
};

} // namespace platform_bus

__BEGIN_CDECLS
zx_status_t platform_proxy_create(void* ctx, zx_device_t* parent, const char* name,
                                  const char* args, zx_handle_t rpc_channel);
__END_CDECLS
