// 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/block.h>
#include <ddktl/protocol/block-internal.h>
#include <zircon/assert.h>
#include <fbl/type_support.h>
#include <fbl/unique_ptr.h>

// DDK block protocol support
//
// :: Mixins ::
//
// ddk::BlockIfc and ddk::BlockProtocol are mixin classes that simplify writing DDK drivers that
// interact with the block protocol. They take care of implementing the function pointer tables
// and calling into the object that wraps them.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_BLOCK_CORE device
// class BlockDevice;
// using BlockDeviceType = ddk::Device<BlockDevice, /* ddk mixins */>;
//
// class BlockDevice : public BlockDeviceType,
//                      public ddk::BlockProtocol<BlockDevice> {
//   public:
//     BlockDevice(zx_device_t* parent)
//       : BlockDeviceType("my-block-device", parent) {}
//
//     zx_status_t Bind() {
//         DdkAdd();
//     }
//
//     void DdkRelease() {
//         // Clean up
//     }
//
//     void BlockSetCallbacks(block_callbacks_t* cb) {
//         // Fill out callbacks
//     }
//
//     ...
//   private:
//     ...
// };

namespace ddk {

template <typename D>
class BlockProtocol : public internal::base_protocol {
  public:
    BlockProtocol() {
        internal::CheckBlockProtocolSubclass<D>();
        ops_.set_callbacks = SetCallbacks;
        ops_.get_info = GetInfo;
        ops_.read = Read;
        ops_.write = Write;

        // Can only inherit from one base_protocol implemenation
        ZX_ASSERT(ddk_proto_ops_ == nullptr);
        ddk_proto_id_ = ZX_PROTOCOL_BLOCK_CORE;
        ddk_proto_ops_ = &ops_;
    }

  private:
    static void SetCallbacks(void* ctx, block_callbacks_t* cb) {
        static_cast<D*>(ctx)->BlockSetCallbacks(cb);
    }

    static void GetInfo(void* ctx, block_info_t* info) {
        static_cast<D*>(ctx)->BlockGetInfo(info);
    }

    static void Read(void* ctx, zx_handle_t vmo, uint64_t length, uint64_t vmo_offset,
                     uint64_t dev_offset, void* cookie) {
        static_cast<D*>(ctx)->BlockRead(vmo, length, vmo_offset, dev_offset, cookie);
    }

    static void Write(void* ctx, zx_handle_t vmo, uint64_t length, uint64_t vmo_offset,
                      uint64_t dev_offset, void* cookie) {
        static_cast<D*>(ctx)->BlockWrite(vmo, length, vmo_offset, dev_offset, cookie);
    }

    block_protocol_ops_t ops_ = {};
};

}  // namespace ddk
