// Copyright 2014 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.

#include "base/json/json_parser.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
#include "chrome/browser/enhanced_bookmarks/android/bookmark_image_service_android.h"
#include "chrome/browser/enhanced_bookmarks/enhanced_bookmark_model_factory.h"
#include "chrome/grit/browser_resources.h"
#include "chrome/renderer/chrome_isolated_world_ids.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/enhanced_bookmarks/enhanced_bookmark_model.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "grit/enhanced_bookmarks_resources.h"
#include "net/base/load_flags.h"
#include "skia/ext/image_operations.h"
#include "ui/base/device_form_factor.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/android/device_display_info.h"
#include "ui/gfx/image/image_skia.h"

using content::Referrer;
using bookmarks::BookmarkNode;

namespace enhanced_bookmarks {

BookmarkImageServiceAndroid::BookmarkImageServiceAndroid(
    content::BrowserContext* browserContext)
    : BookmarkImageService(
          browserContext->GetPath(),
          EnhancedBookmarkModelFactory::GetForBrowserContext(browserContext),
          make_scoped_refptr(content::BrowserThread::GetBlockingPool())),
      browser_context_(browserContext) {
  // The images we're saving will be used locally. So it's wasteful to store
  // images larger than the device resolution.
  gfx::DeviceDisplayInfo display_info;
  int max_length = std::min(display_info.GetPhysicalDisplayWidth(),
                            display_info.GetPhysicalDisplayHeight());
  // GetPhysicalDisplay*() returns 0 for pre-JB MR1. If so, fall back to the
  // second best option we have.
  if (max_length == 0) {
    max_length = std::min(display_info.GetDisplayWidth(),
                          display_info.GetDisplayHeight());
  }

  if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) {
    max_length = max_length / 2;
  } else if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_PHONE) {
    max_length = max_length * 3 / 4;
  }

  DCHECK(max_length > 0);
  max_size_.set_height(max_length);
  max_size_.set_width(max_length);
}

BookmarkImageServiceAndroid::~BookmarkImageServiceAndroid() {
}

void BookmarkImageServiceAndroid::RetrieveSalientImage(
    const GURL& page_url,
    const GURL& image_url,
    const std::string& referrer,
    net::URLRequest::ReferrerPolicy referrer_policy,
    bool update_bookmark) {
  const BookmarkNode* bookmark =
      enhanced_bookmark_model_->bookmark_model()
          ->GetMostRecentlyAddedUserNodeForURL(page_url);
  if (!bookmark || !image_url.is_valid()) {
    ProcessNewImage(page_url, update_bookmark, image_url,
                    scoped_ptr<gfx::Image>(new gfx::Image()));
    return;
  }

  BitmapFetcherHandler* bitmap_fetcher_handler =
      new BitmapFetcherHandler(this, image_url);
  bitmap_fetcher_handler->Start(
      browser_context_, referrer, referrer_policy,
      net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES,
      update_bookmark, page_url);
}

void BookmarkImageServiceAndroid::RetrieveSalientImageFromContext(
    content::WebContents* web_contents,
    const GURL& page_url,
    bool update_bookmark) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (IsPageUrlInProgress(page_url))
    return;  // A request for this URL is already in progress.

  const BookmarkNode* bookmark = enhanced_bookmark_model_->bookmark_model()
          ->GetMostRecentlyAddedUserNodeForURL(page_url);
  if (!bookmark)
    return;

  // Stop the image extraction if there is already an image present.
  GURL url;
  int height, width;
  if (enhanced_bookmark_model_->GetOriginalImage(bookmark, &url, &width,
                                                 &height) ||
      enhanced_bookmark_model_->GetThumbnailImage(bookmark, &url, &width,
                                                  &height)) {
    return;
  }

  if (dom_initializer_script_.empty()) {
    dom_initializer_script_ =
        base::UTF8ToUTF16(
            ResourceBundle::GetSharedInstance()
                .GetRawDataResource(IDR_DOM_INITIALIZER_GEN_JS)
                .as_string());
  }

  blink::WebReferrerPolicy policy =
      web_contents->GetController().GetVisibleEntry()->GetReferrer().policy;

  content::RenderFrameHost* render_frame_host = web_contents->GetMainFrame();

  render_frame_host->ExecuteJavaScriptInIsolatedWorld(
      dom_initializer_script_,
      base::Bind(
          &BookmarkImageServiceAndroid::InitializeDomCallback,
          base::Unretained(this), policy, render_frame_host, page_url,
          update_bookmark),
      chrome::ISOLATED_WORLD_ID_CHROME_INTERNAL);
}

void BookmarkImageServiceAndroid::FinishSuccessfulPageLoadForTab(
    content::WebContents* web_contents, bool update_bookmark) {
  content::NavigationEntry* entry =
      web_contents->GetController().GetVisibleEntry();

  // If the navigation is a simple back or forward, do not extract images, those
  // were extracted already.
  if (!entry || (entry->GetTransitionType() & ui::PAGE_TRANSITION_FORWARD_BACK))
    return;
  const GURL& entry_url = entry->GetURL();
  const GURL& entry_original_url = entry->GetOriginalRequestURL();
  std::vector<GURL> urls;
  urls.push_back(entry_url);
  if (entry_url != entry_original_url)
    urls.push_back(entry_original_url);
  for (GURL url : urls) {
    if (enhanced_bookmark_model_->bookmark_model()->IsBookmarked(url)) {
      RetrieveSalientImageFromContext(web_contents, url,
                                      update_bookmark);
    }
  }
}

void BookmarkImageServiceAndroid::InitializeDomCallback(
    blink::WebReferrerPolicy policy,
    content::RenderFrameHost* render_frame_host,
    const GURL& page_url,
    bool update_bookmark,
    const base::Value* result) {
  if (get_salient_image_url_script_.empty()) {
    get_salient_image_url_script_ =
        base::UTF8ToUTF16(
            ResourceBundle::GetSharedInstance()
                .GetRawDataResource(IDR_GET_SALIENT_IMAGE_URL_GEN_JS)
                .as_string());
  }

  render_frame_host->ExecuteJavaScriptInIsolatedWorld(
      get_salient_image_url_script_,
      base::Bind(
          &BookmarkImageServiceAndroid::RetrieveSalientImageFromContextCallback,
          base::Unretained(this), policy, page_url, update_bookmark),
      chrome::ISOLATED_WORLD_ID_CHROME_INTERNAL);
}

void BookmarkImageServiceAndroid::RetrieveSalientImageFromContextCallback(
    blink::WebReferrerPolicy policy,
    const GURL& page_url,
    bool update_bookmark,
    const base::Value* result) {
  if (!result)
    return;

  std::string json;
  if (!result->GetAsString(&json)) {
    LOG(WARNING)
        << "Salient image extracting script returned non-string result.";
    return;
  }

  int error_code = 0;
  std::string error_message;
  scoped_ptr<base::Value> json_data = base::JSONReader::ReadAndReturnError(
      json, base::JSON_PARSE_RFC, &error_code, &error_message);
  if (error_code || !json_data) {
    LOG(WARNING) << "JSON parse error: " << error_message << json;
    return;
  }

  base::DictionaryValue* dict;
  if (!json_data->GetAsDictionary(&dict)) {
    LOG(WARNING) << "JSON parse error, not a dict: " << json;
    return;
  }

  std::string referrerPolicy;
  std::string image_url;
  dict->GetString("referrerPolicy", &referrerPolicy);
  dict->GetString("imageUrl", &image_url);

  in_progress_page_urls_.insert(page_url);

  Referrer referrer =
      Referrer::SanitizeForRequest(GURL(image_url), Referrer(page_url, policy));
  net::URLRequest::ReferrerPolicy referrer_policy =
      net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
  if (!referrer.url.is_empty()) {
    switch (policy) {
      case blink::WebReferrerPolicyDefault:
        break;
      case blink::WebReferrerPolicyAlways:
      case blink::WebReferrerPolicyNever:
      case blink::WebReferrerPolicyOrigin:
        referrer_policy = net::URLRequest::NEVER_CLEAR_REFERRER;
        break;
      default:
        NOTREACHED();
    }
  }
  RetrieveSalientImage(page_url, GURL(image_url), referrer.url.spec(),
                       referrer_policy, update_bookmark);
}

scoped_ptr<gfx::Image> BookmarkImageServiceAndroid::ResizeImage(
    const gfx::Image& image) {
  DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  scoped_ptr<gfx::Image> result(new gfx::Image());

  if (image.Width() > max_size_.width() &&
      image.Height() > max_size_.height()) {
    float resize_ratio = std::min(
        ((float)max_size_.width()) / image.Width(),
        ((float)max_size_.height()) / image.Height());
    // +0.5f is for correct rounding. Without it, it's possible that dest_width
    // is smaller than max_size_.Width() by one.
    int dest_width = static_cast<int>(resize_ratio * image.Width() + 0.5f);
    int dest_height = static_cast<int>(
        resize_ratio * image.Height() + 0.5f);

    *result = gfx::Image::CreateFrom1xBitmap(
        skia::ImageOperations::Resize(image.AsBitmap(),
                                      skia::ImageOperations::RESIZE_BEST,
                                      dest_width,
                                      dest_height));
    result->AsImageSkia().MakeThreadSafe();
  } else {
    *result = image;
  }

  return result.Pass();
}

void BookmarkImageServiceAndroid::BitmapFetcherHandler::Start(
    content::BrowserContext* browser_context,
    const std::string& referrer,
    net::URLRequest::ReferrerPolicy referrer_policy,
    int load_flags,
    bool update_bookmark,
    const GURL& page_url) {
  update_bookmark_ = update_bookmark;
  page_url_ = page_url;

  bitmap_fetcher_.Init(browser_context->GetRequestContext(), referrer,
                       referrer_policy, load_flags);
  bitmap_fetcher_.Start();
}

void BookmarkImageServiceAndroid::BitmapFetcherHandler::OnFetchComplete(
    const GURL& url,
    const SkBitmap* bitmap) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  scoped_ptr<gfx::Image> image;
  if (bitmap) {
    gfx::ImageSkia imageSkia = gfx::ImageSkia::CreateFrom1xBitmap(*bitmap);
    imageSkia.MakeThreadSafe();
    image.reset(new gfx::Image(imageSkia));
  } else {
    image.reset(new gfx::Image());
  }
  service_->ProcessNewImage(page_url_, update_bookmark_, url, image.Pass());

  delete this;
}

}  // namespace enhanced_bookmarks
