// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * Creates and starts downloading and then resizing of the image. Finally,
 * returns the image using the callback.
 *
 * @param {string} id Request ID.
 * @param {ImageCache} cache Cache object.
 * @param {!PiexLoader} piexLoader Piex loader for RAW file.
 * @param {!LoadImageRequest} request Request message as a hash array.
 * @param {function(!LoadImageResponse)} callback Response handler.
 * @constructor
 */
function ImageRequest(id, cache, piexLoader, request, callback) {
  /**
   * Global ID (concatenated client ID and client request ID).
   * @type {string}
   * @private
   */
  this.id_ = id;

  /**
   * @type {ImageCache}
   * @private
   */
  this.cache_ = cache;

  /**
   * @type {!PiexLoader}
   * @private
   */
  this.piexLoader_ = piexLoader;

  /**
   * @type {!LoadImageRequest}
   * @private
   */
  this.request_ = request;

  /**
   * @type {function(!LoadImageResponse)}
   * @private
   */
  this.sendResponse_ = callback;

  /**
   * Temporary image used to download images.
   * @type {Image}
   * @private
   */
  this.image_ = new Image();

  /**
   * MIME type of the fetched image.
   * @type {?string}
   * @private
   */
  this.contentType_ = null;

  /**
   * Used to download remote images using http:// or https:// protocols.
   * @type {AuthorizedXHR}
   * @private
   */
  this.xhr_ = new AuthorizedXHR();

  /**
   * Temporary canvas used to resize and compress the image.
   * @type {HTMLCanvasElement}
   * @private
   */
  this.canvas_ =
      /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));

  /**
   * @type {CanvasRenderingContext2D}
   * @private
   */
  this.context_ =
      /** @type {CanvasRenderingContext2D} */ (this.canvas_.getContext('2d'));

  /**
   * Callback to be called once downloading is finished.
   * @type {?function()}
   * @private
   */
  this.downloadCallback_ = null;
}

/**
 * Seeks offset to generate video thumbnail.
 * TODO(ryoh):
 *   What is the best position for the thumbnail?
 *   The first frame seems not good -- sometimes it is a black frame.
 * @const
 * @type {number}
 */
ImageRequest.VIDEO_THUMBNAIL_POSITION = 3; // [sec]

/**
 * The maximum milliseconds to load video. If loading video exceeds the limit,
 * we give up generating video thumbnail and free the consumed memory.
 * @const
 * @type {number}
 */
ImageRequest.MAX_MILLISECONDS_TO_LOAD_VIDEO = 3000;

/**
 * Returns ID of the request.
 * @return {string} Request ID.
 */
ImageRequest.prototype.getId = function() {
  return this.id_;
};

/**
 * Returns the client's task ID for the request.
 * @return {number}
 */
ImageRequest.prototype.getClientTaskId = function() {
  // Every incoming request should have been given a taskId.
  assert(this.request_.taskId);
  return this.request_.taskId;
};

/**
 * Returns priority of the request. The higher priority, the faster it will
 * be handled. The highest priority is 0. The default one is 2.
 *
 * @return {number} Priority.
 */
ImageRequest.prototype.getPriority = function() {
  return (this.request_.priority !== undefined) ? this.request_.priority : 2;
};

/**
 * Tries to load the image from cache if exists and sends the response.
 *
 * @param {function()} onSuccess Success callback.
 * @param {function()} onFailure Failure callback.
 */
ImageRequest.prototype.loadFromCacheAndProcess = function(
    onSuccess, onFailure) {
  this.loadFromCache_(
      function(data, width, height) {  // Found in cache.
        this.sendImageData_(data, width, height);
        onSuccess();
      }.bind(this),
      onFailure);  // Not found in cache.
};

/**
 * Tries to download the image, resizes and sends the response.
 * @param {function()} callback Completion callback.
 */
ImageRequest.prototype.downloadAndProcess = function(callback) {
  if (this.downloadCallback_) {
    throw new Error('Downloading already started.');
  }

  this.downloadCallback_ = callback;
  this.downloadOriginal_(this.onImageLoad_.bind(this),
                         this.onImageError_.bind(this));
};

/**
 * Fetches the image from the persistent cache.
 *
 * @param {function(string, number, number)} onSuccess Success callback.
 * @param {function()} onFailure Failure callback.
 * @private
 */
ImageRequest.prototype.loadFromCache_ = function(onSuccess, onFailure) {
  let cacheKey = LoadImageRequest.cacheKey(this.request_);

  if (!cacheKey) {
    // Cache key is not provided for the request.
    onFailure();
    return;
  }

  if (!this.request_.cache) {
    // Cache is disabled for this request; therefore, remove it from cache
    // if existed.
    this.cache_.removeImage(cacheKey);
    onFailure();
    return;
  }

  if (!this.request_.timestamp) {
    // Persistent cache is available only when a timestamp is provided.
    onFailure();
    return;
  }

  this.cache_.loadImage(cacheKey,
                        this.request_.timestamp,
                        onSuccess,
                        onFailure);
};

/**
 * Saves the image to the persistent cache.
 *
 * @param {string} data The image's data.
 * @param {number} width Image width.
 * @param {number} height Image height.
 * @private
 */
ImageRequest.prototype.saveToCache_ = function(data, width, height) {
  if (!this.request_.cache || !this.request_.timestamp) {
    // Persistent cache is available only when a timestamp is provided.
    return;
  }

  let cacheKey = LoadImageRequest.cacheKey(this.request_);
  if (!cacheKey) {
    // Cache key is not provided for the request.
    return;
  }

  this.cache_.saveImage(cacheKey,
                        data,
                        width,
                        height,
                        this.request_.timestamp);
};

/**
 * Downloads an image directly or for remote resources using the XmlHttpRequest.
 *
 * @param {function()} onSuccess Success callback.
 * @param {function()} onFailure Failure callback.
 * @private
 */
ImageRequest.prototype.downloadOriginal_ = function(onSuccess, onFailure) {
  this.image_.onload = function() {
    URL.revokeObjectURL(this.image_.src);
    onSuccess();
  }.bind(this);
  this.image_.onerror = function() {
    URL.revokeObjectURL(this.image_.src);
    onFailure();
  }.bind(this);

  // Download data urls directly since they are not supported by XmlHttpRequest.
  var dataUrlMatches = this.request_.url.match(/^data:([^,;]*)[,;]/);
  if (dataUrlMatches) {
    this.image_.src = this.request_.url;
    this.contentType_ = dataUrlMatches[1];
    return;
  }
  var drivefsUrlMatches = this.request_.url.match(/^drivefs:(.*)/);
  if (drivefsUrlMatches) {
    window.webkitResolveLocalFileSystemURL(
        drivefsUrlMatches[1],
        entry => {
          chrome.fileManagerPrivate.getThumbnail(
              entry, !!this.request_.crop, thumbnail => {
                if (!thumbnail) {
                  onFailure();
                  return;
                }
                this.image_.src = thumbnail;
                this.contentType_ = 'image/png';
              });
        },
        error => {
          onFailure();
        });
    return;
  }

  var fileType = FileType.getTypeForName(this.request_.url);

  // Load RAW images by using Piex loader instead of XHR.
  if (fileType.type === 'raw') {
    this.piexLoader_.load(this.request_.url).then(function(data) {
      var blob = new Blob([data.thumbnail], {type: 'image/jpeg'});
      var url = URL.createObjectURL(blob);
      this.image_.src = url;
      this.request_.orientation = data.orientation;
      this.request_.colorSpace = data.colorSpace;
    }.bind(this), function() {
      // The error has already been logged in PiexLoader.
      onFailure();
    });
    return;
  }

  // Load video thumbnails by using video tag instead of XHR.
  if (fileType.type === 'video') {
    this.createVideoThumbnailUrl_(this.request_.url).then(function(url) {
      this.image_.src = url;
    }.bind(this)).catch(function(error) {
      console.error('Video thumbnail error: ', error);
      onFailure();
    });
    return;
  }

  // Fetch the image via authorized XHR and parse it.
  var parseImage = function(contentType, blob) {
    if (contentType) {
      this.contentType_ = contentType;
    }
    this.image_.src = URL.createObjectURL(blob);
  }.bind(this);

  // Request raw data via XHR.
  this.xhr_.load(this.request_.url, parseImage, onFailure);
};

/**
 * Creates a video thumbnail data url from video file.
 *
 * @param {string} url Video URL.
 * @return {!Promise<Blob>}  Promise that resolves with the data url of video
 *    thumbnail.
 * @private
 */
ImageRequest.prototype.createVideoThumbnailUrl_ = function(url) {
  const video =
      assertInstanceof(document.createElement('video'), HTMLVideoElement);
  return Promise
      .race([
        new Promise((resolve, reject) => {
          video.addEventListener('canplay', resolve);
          video.addEventListener('error', reject);
          video.currentTime = ImageRequest.VIDEO_THUMBNAIL_POSITION;
          video.preload = 'auto';
          video.src = url;
          video.load();
        }),
        new Promise((resolve) => {
          setTimeout(resolve, ImageRequest.MAX_MILLISECONDS_TO_LOAD_VIDEO);
        }).then(() => {
          // If we don't receive 'canplay' event after 3 seconds have passed for
          // some reason (e.g. unseekable video), we give up generating
          // thumbnail.
          video.src =
              '';  // Make sure to stop loading remaining part of the video.
          throw new Error('Seeking video failed.');
        })
      ])
      .then(() => {
        const canvas = assertInstanceof(
            document.createElement('canvas'), HTMLCanvasElement);
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        assertInstanceof(canvas.getContext('2d'), CanvasRenderingContext2D)
            .drawImage(video, 0, 0);
        return canvas.toDataURL();
      });
};

/**
 * Creates a XmlHttpRequest wrapper with injected OAuth2 authentication headers.
 * @constructor
 */
function AuthorizedXHR() {
  this.xhr_ = null;
  this.aborted_ = false;
}

/**
 * A map which is used to estimate content type from extension.
 * @enum {string}
 */
AuthorizedXHR.ExtensionContentTypeMap = {
  gif: 'image/gif',
  png: 'image/png',
  svg: 'image/svg',
  bmp: 'image/bmp',
  jpg: 'image/jpeg',
  jpeg: 'image/jpeg'
};

/**
 * Aborts the current request (if running).
 */
AuthorizedXHR.prototype.abort = function() {
  this.aborted_ = true;
  if (this.xhr_) {
    this.xhr_.abort();
  }
};

/**
 * Loads an image using a OAuth2 token. If it fails, then tries to retry with
 * a refreshed OAuth2 token.
 *
 * @param {string} url URL to the resource to be fetched.
 * @param {function(string, Blob)} onSuccess Success callback with the content
 *     type and the fetched data.
 * @param {function()} onFailure Failure callback.
 */
AuthorizedXHR.prototype.load = function(url, onSuccess, onFailure) {
  this.aborted_ = false;

  // Do not call any callbacks when aborting.
  var onMaybeSuccess = /** @type {function(string, Blob)} */ (
      function(contentType, response) {
        // When content type is not available, try to estimate it from url.
        if (!contentType) {
          contentType = AuthorizedXHR.ExtensionContentTypeMap[
              this.extractExtension_(url)];
        }

        if (!this.aborted_) {
          onSuccess(contentType, response);
        }
      }.bind(this));

  var onMaybeFailure = /** @type {function(number=)} */ (function(opt_code) {
    if (!this.aborted_) {
      onFailure();
    }
  }.bind(this));

  // Fetches the access token and makes an authorized call. If refresh is true,
  // then forces refreshing the access token.
  var requestTokenAndCall = function(refresh, onInnerSuccess, onInnerFailure) {
    chrome.fileManagerPrivate.requestAccessToken(refresh, function(token) {
      if (this.aborted_) {
        return;
      }
      if (!token) {
        onInnerFailure();
        return;
      }
      this.xhr_ = AuthorizedXHR.load_(
          token, url, onInnerSuccess, onInnerFailure);
    }.bind(this));
  }.bind(this);

  // Refreshes the access token and retries the request.
  var maybeRetryCall = function(code) {
    if (this.aborted_) {
      return;
    }
    requestTokenAndCall(true, onMaybeSuccess, onMaybeFailure);
  }.bind(this);

  // Do not request a token for local resources, since it is not necessary.
  if (/^filesystem:/.test(url)) {
    // The query parameter is workaround for
    // crbug.com/379678, which force to obtain the latest contents of the image.
    var noCacheUrl = url + '?nocache=' + Date.now();
    this.xhr_ = AuthorizedXHR.load_(
        null,
        noCacheUrl,
        onMaybeSuccess,
        onMaybeFailure);
    return;
  }

  // Make the request with reusing the current token. If it fails, then retry.
  requestTokenAndCall(false, onMaybeSuccess, maybeRetryCall);
};

/**
 * Extracts extension from url.
 * @param {string} url Url.
 * @return {string} Extracted extensiion, e.g. png.
 */
AuthorizedXHR.prototype.extractExtension_ = function(url) {
  var result = (/\.([a-zA-Z]+)$/i).exec(url);
  return result ? result[1] : '';
};

/**
 * Fetches data using authorized XmlHttpRequest with the provided OAuth2 token.
 * If the token is invalid, the request will fail.
 *
 * @param {?string} token OAuth2 token to be injected to the request. Null for
 *     no token.
 * @param {string} url URL to the resource to be fetched.
 * @param {function(string, Blob)} onSuccess Success callback with the content
 *     type and the fetched data.
 * @param {function(number=)} onFailure Failure callback with the error code
 *     if available.
 * @return {XMLHttpRequest} XHR instance.
 * @private
 */
AuthorizedXHR.load_ = function(token, url, onSuccess, onFailure) {
  let xhr = new XMLHttpRequest();
  xhr.responseType = 'blob';

  xhr.onreadystatechange = function() {
    if (xhr.readyState != 4) {
      return;
    }
    if (xhr.status != 200) {
      onFailure(xhr.status);
      return;
    }
    let response = /** @type {Blob} */ (xhr.response);
    let contentType = xhr.getResponseHeader('Content-Type') || response.type;
    onSuccess(contentType, response);
  }.bind(this);

  // Perform a xhr request.
  try {
    xhr.open('GET', url, true);
    if (token) {
      xhr.setRequestHeader('Authorization', 'Bearer ' + token);
    }
    xhr.send();
  } catch (e) {
    onFailure();
  }

  return xhr;
};

/**
 * Sends the resized image via the callback. If the image has been changed,
 * then packs the canvas contents, otherwise sends the raw image data.
 *
 * @param {boolean} imageChanged Whether the image has been changed.
 * @private
 */
ImageRequest.prototype.sendImage_ = function(imageChanged) {
  var imageData;
  var width;
  var height;
  if (!imageChanged) {
    // The image hasn't been processed, so the raw data can be directly
    // forwarded for speed (no need to encode the image again).
    imageData = this.image_.src;
    width = this.image_.width;
    height = this.image_.height;
  } else {
    // The image has been resized or rotated, therefore the canvas has to be
    // encoded to get the correct compressed image data.
    width = this.canvas_.width;
    height = this.canvas_.height;

    switch (this.contentType_) {
      case 'image/gif':
      case 'image/png':
      case 'image/svg':
      case 'image/bmp':
        imageData = this.canvas_.toDataURL('image/png');
        break;
      case 'image/jpeg':
      default:
        imageData = this.canvas_.toDataURL('image/jpeg', 0.9);
    }
  }

  // Send and store in the persistent cache.
  this.sendImageData_(imageData, width, height);
  this.saveToCache_(imageData, width, height);
};

/**
 * Sends the resized image via the callback.
 * @param {string} data Compressed image data.
 * @param {number} width Width.
 * @param {number} height Height.
 * @private
 */
ImageRequest.prototype.sendImageData_ = function(data, width, height) {
  this.sendResponse_(new LoadImageResponse(
      LoadImageResponseStatus.SUCCESS, this.getClientTaskId(),
      {width: width, height: height, data: data}));
};

/**
 * Handler, when contents are loaded into the image element. Performs resizing
 * and finalizes the request process.
 * @private
 */
ImageRequest.prototype.onImageLoad_ = function() {
  // Perform processing if the url is not a data url, or if there are some
  // operations requested.
  if (!(this.request_.url.match(/^data/) ||
        this.request_.url.match(/^drivefs:/)) ||
      ImageLoaderUtil.shouldProcess(
          this.image_.width, this.image_.height, this.request_)) {
    ImageLoaderUtil.resizeAndCrop(this.image_, this.canvas_, this.request_);
    ImageLoaderUtil.convertColorSpace(
        this.canvas_, this.request_.colorSpace || ColorSpace.SRGB);
    this.sendImage_(true);  // Image changed.
  } else {
    this.sendImage_(false);  // Image not changed.
  }
  this.cleanup_();
  this.downloadCallback_();
};

/**
 * Handler, when loading of the image fails. Sends a failure response and
 * finalizes the request process.
 * @private
 */
ImageRequest.prototype.onImageError_ = function() {
  this.sendResponse_(new LoadImageResponse(
      LoadImageResponseStatus.ERROR, this.getClientTaskId()));
  this.cleanup_();
  this.downloadCallback_();
};

/**
 * Cancels the request.
 */
ImageRequest.prototype.cancel = function() {
  this.cleanup_();

  // If downloading has started, then call the callback.
  if (this.downloadCallback_) {
    this.downloadCallback_();
  }
};

/**
 * Cleans up memory used by this request.
 * @private
 */
ImageRequest.prototype.cleanup_ = function() {
  this.image_.onerror = function() {};
  this.image_.onload = function() {};

  // Transparent 1x1 pixel gif, to force garbage collecting.
  this.image_.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAA' +
      'ABAAEAAAICTAEAOw==';

  this.xhr_.abort();

  // Dispose memory allocated by Canvas.
  this.canvas_.width = 0;
  this.canvas_.height = 0;
};
