// 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 <ostream>
#include <string>

#include <base/basictypes.h>
#include <base/callback.h>
#include <base/memory/scoped_ptr.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 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* 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_;
  scoped_ptr<uint8[]> 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_
