// 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 "chrome/browser/android/logo_service.h"

#include "base/memory/weak_ptr.h"
#include "chrome/browser/google/google_profile_helper.h"
#include "chrome/browser/image_decoder.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "components/google/core/browser/google_util.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/search_engines/template_url_service.h"
#include "components/search_provider_logos/google_logo_api.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request_context_getter.h"

using content::BrowserThread;
using search_provider_logos::Logo;
using search_provider_logos::LogoDelegate;
using search_provider_logos::LogoTracker;

namespace {

const char kGoogleDoodleURLPath[] = "async/newtab_mobile";
const char kCachedLogoDirectory[] = "Search Logo";
const int kDecodeLogoTimeoutSeconds = 30;

// Returns the URL where the doodle can be downloaded, e.g.
// https://www.google.com/async/newtab_mobile. This depends on the user's
// Google domain.
GURL GetGoogleDoodleURL(Profile* profile) {
  // SetPathStr() requires its argument to stay in scope as long as
  // |replacements| is, so a std::string is needed, instead of a char*.
  std::string path = kGoogleDoodleURLPath;
  GURL::Replacements replacements;
  replacements.SetPathStr(path);

  GURL base_url(google_util::CommandLineGoogleBaseURL());
  if (!base_url.is_valid())
    base_url = google_profile_helper::GetGoogleHomePageURL(profile);
  return base_url.ReplaceComponents(replacements);
}

class LogoDecoderDelegate : public ImageDecoder::Delegate {
 public:
  LogoDecoderDelegate(
      const scoped_refptr<ImageDecoder>& image_decoder,
      const base::Callback<void(const SkBitmap&)>& image_decoded_callback)
      : image_decoder_(image_decoder),
        image_decoded_callback_(image_decoded_callback),
        weak_ptr_factory_(this) {
    // If the ImageDecoder crashes or otherwise never completes, call
    // OnImageDecodeTimedOut() eventually to ensure that image_decoded_callback_
    // is run.
    base::MessageLoopProxy::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&LogoDecoderDelegate::OnDecodeImageFailed,
                   weak_ptr_factory_.GetWeakPtr(),
                   (const ImageDecoder*) NULL),
        base::TimeDelta::FromSeconds(kDecodeLogoTimeoutSeconds));
  }

  virtual ~LogoDecoderDelegate() {
    image_decoder_->set_delegate(NULL);
  }

  // ImageDecoder::Delegate:
  virtual void OnImageDecoded(const ImageDecoder* decoder,
                              const SkBitmap& decoded_image) override {
    image_decoded_callback_.Run(decoded_image);
    delete this;
  }

  virtual void OnDecodeImageFailed(const ImageDecoder* decoder) override {
    image_decoded_callback_.Run(SkBitmap());
    delete this;
  }

 private:
  scoped_refptr<ImageDecoder> image_decoder_;
  base::Callback<void(const SkBitmap&)> image_decoded_callback_;
  base::WeakPtrFactory<LogoDecoderDelegate> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(LogoDecoderDelegate);
};

class ChromeLogoDelegate : public search_provider_logos::LogoDelegate {
 public:
  ChromeLogoDelegate() {}
  virtual ~ChromeLogoDelegate() {}

  // search_provider_logos::LogoDelegate:
  virtual void DecodeUntrustedImage(
      const scoped_refptr<base::RefCountedString>& encoded_image,
      base::Callback<void(const SkBitmap&)> image_decoded_callback) override {
    scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder(
        NULL,
        encoded_image->data(),
        ImageDecoder::DEFAULT_CODEC);
    LogoDecoderDelegate* delegate =
        new LogoDecoderDelegate(image_decoder, image_decoded_callback);
    image_decoder->set_delegate(delegate);
    image_decoder->Start(base::MessageLoopProxy::current());
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ChromeLogoDelegate);
};

}  // namespace

// LogoService ----------------------------------------------------------------

LogoService::LogoService(Profile* profile) : profile_(profile) {
}

LogoService::~LogoService() {
}

void LogoService::GetLogo(search_provider_logos::LogoObserver* observer) {
  TemplateURLService* template_url_service =
      TemplateURLServiceFactory::GetForProfile(profile_);
  if (!template_url_service)
    return;

  TemplateURL* template_url = template_url_service->GetDefaultSearchProvider();
  if (!template_url || !template_url->url_ref().HasGoogleBaseURLs(
          template_url_service->search_terms_data()))
    return;

  if (!logo_tracker_) {
    logo_tracker_.reset(new LogoTracker(
        profile_->GetPath().Append(kCachedLogoDirectory),
        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
        BrowserThread::GetBlockingPool(),
        profile_->GetRequestContext(),
        scoped_ptr<search_provider_logos::LogoDelegate>(
            new ChromeLogoDelegate())));
  }

  logo_tracker_->SetServerAPI(
      GetGoogleDoodleURL(profile_),
      base::Bind(&search_provider_logos::GoogleParseLogoResponse),
      base::Bind(&search_provider_logos::GoogleAppendFingerprintToLogoURL));
  logo_tracker_->GetLogo(observer);
}

// LogoServiceFactory ---------------------------------------------------------

// static
LogoService* LogoServiceFactory::GetForProfile(Profile* profile) {
  return static_cast<LogoService*>(
      GetInstance()->GetServiceForBrowserContext(profile, true));
}

// static
LogoServiceFactory* LogoServiceFactory::GetInstance() {
  return Singleton<LogoServiceFactory>::get();
}

LogoServiceFactory::LogoServiceFactory()
    : BrowserContextKeyedServiceFactory(
          "LogoService",
          BrowserContextDependencyManager::GetInstance()) {
}

LogoServiceFactory::~LogoServiceFactory() {}

KeyedService* LogoServiceFactory::BuildServiceInstanceFor(
    content::BrowserContext* context) const {
  Profile* profile = static_cast<Profile*>(context);
  DCHECK(!profile->IsOffTheRecord());
  return new LogoService(profile);
}
