// Copyright (c) 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.

#include "android_webview/browser/icon_helper.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/hash.h"
#include "base/logging.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/favicon_url.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/geometry/size.h"

using content::BrowserThread;
using content::WebContents;

namespace android_webview {

IconHelper::IconHelper(WebContents* web_contents)
    : WebContentsObserver(web_contents),
      listener_(NULL),
      missing_favicon_urls_() {
}

IconHelper::~IconHelper() {
}

void IconHelper::SetListener(Listener* listener) {
  listener_ = listener;
}

void IconHelper::DownloadFaviconCallback(
    int id,
    int http_status_code,
    const GURL& image_url,
    const std::vector<SkBitmap>& bitmaps,
    const std::vector<gfx::Size>& original_bitmap_sizes) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (http_status_code == 404) {
    MarkUnableToDownloadFavicon(image_url);
    return;
  }

  if (bitmaps.size() == 0) {
    return;
  }

  // We can protentially have multiple frames of the icon
  // in different sizes. We need more fine grain API spec
  // to let clients pick out the frame they want.

  // TODO(acleung): Pick the best icon to return based on size.
  if (listener_)
    listener_->OnReceivedIcon(image_url, bitmaps[0]);
}

void IconHelper::DidUpdateFaviconURL(
    const std::vector<content::FaviconURL>& candidates) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  for (std::vector<content::FaviconURL>::const_iterator i = candidates.begin();
       i != candidates.end(); ++i) {
    if (!i->icon_url.is_valid())
      continue;

    switch(i->icon_type) {
      case content::FaviconURL::IconType::kFavicon:
        if ((listener_ && !listener_->ShouldDownloadFavicon(i->icon_url)) ||
            WasUnableToDownloadFavicon(i->icon_url)) {
          break;
        }
        web_contents()->DownloadImage(i->icon_url,
            true,  // Is a favicon
            0,  // No maximum size
            false,  // Normal cache policy
            base::Bind(
                &IconHelper::DownloadFaviconCallback, base::Unretained(this)));
        break;
      case content::FaviconURL::IconType::kTouchIcon:
        if (listener_)
          listener_->OnReceivedTouchIconUrl(i->icon_url.spec(), false);
        break;
      case content::FaviconURL::IconType::kTouchPrecomposedIcon:
        if (listener_)
          listener_->OnReceivedTouchIconUrl(i->icon_url.spec(), true);
        break;
      case content::FaviconURL::IconType::kInvalid:
        // Silently ignore it. Only trigger a callback on valid icons.
        break;
      default:
        NOTREACHED();
        break;
    }
  }
}

void IconHelper::DidStartNavigationToPendingEntry(
    const GURL& url,
    content::ReloadType reload_type) {
  if (reload_type == content::ReloadType::BYPASSING_CACHE)
    ClearUnableToDownloadFavicons();
}

void IconHelper::MarkUnableToDownloadFavicon(const GURL& icon_url) {
  MissingFaviconURLHash url_hash = base::Hash(icon_url.spec());
  missing_favicon_urls_.insert(url_hash);
}

bool IconHelper::WasUnableToDownloadFavicon(const GURL& icon_url) const {
  MissingFaviconURLHash url_hash = base::Hash(icon_url.spec());
  return missing_favicon_urls_.find(url_hash) != missing_favicon_urls_.end();
}

void IconHelper::ClearUnableToDownloadFavicons() {
  missing_favicon_urls_.clear();
}

}  // namespace android_webview
