library googleapis_beta.common;

import 'dart:async' as async;
import 'dart:core' as core;
import 'dart:collection' as collection;
/**
 * Represents a media consisting of a stream of bytes, a content type and a
 * length.
 */
class Media {
  final async.Stream<core.List<core.int>> stream;
  final core.String contentType;
  final core.int length;

  /**
   * Creates a new [Media] with a byte [stream] of length [length] with a
   * [contentType].
   *
   * When uploading media, [length] can only be null if [ResumableUploadOptions]
   * is used.
   */
  Media(this.stream, this.length,
        {this.contentType: "application/octet-stream"}) {
    if (stream == null || contentType == null) {
      throw new core.ArgumentError(
          'Arguments stream, contentType and length must not be null.');
    }
    if (length != null && length < 0) {
      throw new core.ArgumentError('A negative content length is not allowed');
    }
  }
}


/**
 * Represents options for uploading a [Media].
 */
class UploadOptions {
  /** Use either simple uploads (only media) or multipart for media+metadata */
  static const UploadOptions Default = const UploadOptions();

  /** Make resumable uploads */
  static final ResumableUploadOptions Resumable = new ResumableUploadOptions();

  const UploadOptions();
}


/**
 * Specifies options for resumable uploads.
 */
class ResumableUploadOptions extends UploadOptions {
  static final core.Function ExponentialBackoff = (core.int failedAttempts) {
    // Do not retry more than 5 times.
    if (failedAttempts > 5) return null;

    // Wait for 2^(failedAttempts-1) seconds, before retrying.
    // i.e. 1 second, 2 seconds, 4 seconds, ...
    return new core.Duration(seconds: 1 << (failedAttempts - 1));
  };

  /**
   * Maximum number of upload attempts per chunk.
   */
  final core.int numberOfAttempts;

  /**
   * Preferred size (in bytes) of a uploaded chunk.
   * Must be a multiple of 256 KB.
   *
   * The default is 1 MB.
   */
  final core.int chunkSize;

  /**
   * Function for determining the [core.Duration] to wait before making the
   * next attempt. See [ExponentialBackoff] for an example.
   */
  final core.Function backoffFunction;

  ResumableUploadOptions({this.numberOfAttempts: 3,
                          this.chunkSize: 1024 * 1024,
                          core.Function backoffFunction})
      : backoffFunction = backoffFunction == null ?
          ExponentialBackoff : backoffFunction {
    // See e.g. here:
    // https://developers.google.com/maps-engine/documentation/resumable-upload
    //
    // Chunk size restriction:
    // There are some chunk size restrictions based on the size of the file you
    // are uploading. Files larger than 256 KB (256 x 1024 bytes) must have
    // chunk sizes that are multiples of 256 KB. For files smaller than 256 KB,
    // there are no restrictions. In either case, the final chunk has no
    // limitations; you can simply transfer the remaining bytes. If you use
    // chunking, it is important to keep the chunk size as large as possible
    // to keep the upload efficient.
    //
    if (numberOfAttempts < 1 || (chunkSize % (256 * 1024)) != 0) {
      throw new core.ArgumentError('Invalid arguments.');
    }
  }
}


/**
 * Represents options for downloading media.
 *
 * For partial downloads, see [PartialDownloadOptions].
 */
class DownloadOptions {
  /** Download only metadata. */
  static const DownloadOptions Metadata = const DownloadOptions();

  /** Download full media. */
  static final PartialDownloadOptions FullMedia =
      new PartialDownloadOptions(new ByteRange(0, -1));

  const DownloadOptions();

  /** Indicates whether metadata should be downloaded. */
  core.bool get isMetadataDownload => true;
}


/**
 * Options for downloading a [Media].
 */
class PartialDownloadOptions extends DownloadOptions {
  /** The range of bytes to be downloaded */
  final ByteRange range;

  PartialDownloadOptions(this.range);

  core.bool get isMetadataDownload => false;

  /**
   * `true` if this is a full download and `false` if this is a partial
   * download.
   */
  core.bool get isFullDownload => range.start == 0 && range.end == -1;
}


/**
 * Specifies a range of media.
 */
class ByteRange {
  /** First byte of media. */
  final core.int start;

  /** Last byte of media (inclusive) */
  final core.int end;

  /** Length of this range (i.e. number of bytes) */
  core.int get length => end - start + 1;

  ByteRange(this.start, this.end) {
    if (!(start == 0  && end == -1 || start >= 0 && end > start)) {
      throw new core.ArgumentError('Invalid media range [$start, $end]');
    }
  }
}


/**
 * Represents a general error reported by the API endpoint.
 */
class ApiRequestError extends core.Error {
  final core.String message;

  ApiRequestError(this.message);

  core.String toString() => 'ApiRequestError(message: $message)';
}

/**
 * Represents a specific error reported by the API endpoint.
 */
class DetailedApiRequestError extends ApiRequestError {
  final core.int status;

  DetailedApiRequestError(this.status, core.String message) : super(message);

  core.String toString()
      => 'DetailedApiRequestError(status: $status, message: $message)';
}
