// Copyright (c) 2013 The Chromium OS 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 MIST_USB_TRANSFER_H_
#define MIST_USB_TRANSFER_H_

#include <stdint.h>

#include <memory>
#include <ostream>  // NOLINT(readability/streams)
#include <string>

#include <base/callback.h>
#include <base/macros.h>
#include <gtest/gtest_prod.h>

#include "mist/usb_constants.h"
#include "mist/usb_error.h"

struct libusb_transfer;

namespace mist {

// A base class encapsulating a USB transfer, which wraps a libusb_transfer C
// struct from libusb 1.0 into a C++ object. This class does not implement a
// specific type of transfer, so it cannot be instantiated and must be extended
// for each type of transfer. In particular, a derived class should set up the
// wrapped libusb_transfer accordingly for a specific type of transfer.
class UsbTransfer {
 public:
  typedef base::Callback<void(UsbTransfer* transfer)> CompletionCallback;

  enum State {
    kIdle,
    kInProgress,
    kCancelling
  };

  ~UsbTransfer();

  // Submits this USB transfer, which will happen asynchronously. Returns true
  // on success. If the underlying libusb_transfer struct is not allocated, sets
  // |error_| to UsbError::kErrorTransferNotAllocated and returns false. If this
  // transfer has been submitted and is still in progress, sets |error_| to
  // UsbError::kErrorTransferAlreadySubmitted and returns false. Upon the
  // completion of this transfer, |completion_callback| is invoked. It is ok to
  // submit this transfer again after completion.
  bool Submit(const CompletionCallback& completion_callback);

  // Cancels this USB transfer if it has been submitted via Submit(). Returns
  // true on success. If this transfer has not been submitted, sets |error_| to
  // UsbError::kErrorTransferNotSubmitted and returns false. If a previous
  // cancellation is already in progress, sets |error_| to
  // UsbError::kErrorTransferBeingCancelled and returns false. The cancellation
  // may not have completed when this method returns. Once this transfer is
  // completely cancelled, |completion_callback_| is invoked.
  bool Cancel();

  // Getters for retrieving fields of the libusb_transfer struct.
  uint8_t GetEndpointAddress() const;
  UsbTransferType GetType() const;
  UsbTransferStatus GetStatus() const;
  int GetLength() const;
  int GetActualLength() const;

  // Returns true if this tranfer is completed with the expected length, i.e.
  // GetStatus() returns kUsbTransferStatusCompleted and GetActualLength()
  // returns |expected_length|.
  bool IsCompletedWithExpectedLength(int expected_length) const;

  // Returns a string describing the properties of this object for logging
  // purpose.
  std::string ToString() const;

  uint8_t* buffer() { return buffer_.get(); }
  int buffer_length() const { return buffer_length_; }
  State state() const { return state_; }
  const UsbError& error() const { return error_; }

 protected:
  UsbTransfer();

  // Verifies that the underlying libusb_transfer struct is allocated,
  // and if so, returns true. Otherwise, set |error_| to
  // UsbError::kErrorTransferNotAllocated and returns false.
  bool VerifyAllocated();

  // Allocates the underlying libusb_transfer struct with |num_iso_packets|
  // isochronous packet descriptors. Returns true on success.
  bool Allocate(int num_iso_packets);

  // Frees the underlying libusb_transfer struct.
  void Free();

  // Allocates the transfer buffer to hold |length| bytes of data. Return true
  // on success.
  bool AllocateBuffer(int length);

  // Called by libusb upon the completion of the underlying USB transfer.
  // A derived class associates this callback to the underlying libusb_transfer
  // struct when setting the transfer.
  static void OnCompleted(libusb_transfer* transfer);

  // Completes the transfer by invoking the completion callback.
  void Complete();

  libusb_transfer* transfer() const { return transfer_; }
  UsbError* mutable_error() { return &error_; }

 private:
  friend class UsbTransferTest;
  FRIEND_TEST(UsbTransferTest, AllocateAfterAllocate);
  FRIEND_TEST(UsbTransferTest, AllocateBuffer);
  FRIEND_TEST(UsbTransferTest, AllocateBufferAfterSubmit);
  FRIEND_TEST(UsbTransferTest, FreeBeforeAllocate);
  FRIEND_TEST(UsbTransferTest, GetType);
  FRIEND_TEST(UsbTransferTest, VerifyAllocated);

  libusb_transfer* transfer_;
  std::unique_ptr<uint8_t[]> buffer_;
  int buffer_length_;
  State state_;
  CompletionCallback completion_callback_;
  UsbError error_;

  DISALLOW_COPY_AND_ASSIGN(UsbTransfer);
};

}  // namespace mist

// Output stream operator provided to facilitate logging.
std::ostream& operator<<(std::ostream& stream,
                         const mist::UsbTransfer& transfer);

#endif  // MIST_USB_TRANSFER_H_
