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

#include "components/dom_distiller/core/dom_distiller_service.h"

#include "base/guid.h"
#include "base/message_loop/message_loop.h"
#include "components/dom_distiller/core/distilled_content_store.h"
#include "components/dom_distiller/core/dom_distiller_store.h"
#include "components/dom_distiller/core/proto/distilled_article.pb.h"
#include "components/dom_distiller/core/task_tracker.h"
#include "url/gurl.h"

namespace dom_distiller {

namespace {

ArticleEntry CreateSkeletonEntryForUrl(const GURL& url) {
  ArticleEntry skeleton;
  skeleton.set_entry_id(base::GenerateGUID());
  ArticleEntryPage* page = skeleton.add_pages();
  page->set_url(url.spec());

  DCHECK(IsEntryValid(skeleton));
  return skeleton;
}

void RunArticleAvailableCallback(
    const DomDistillerService::ArticleAvailableCallback& article_cb,
    const ArticleEntry& entry,
    const DistilledArticleProto* article_proto,
    bool distillation_succeeded) {
  article_cb.Run(distillation_succeeded);
}

}  // namespace

DomDistillerService::DomDistillerService(
    scoped_ptr<DomDistillerStoreInterface> store,
    scoped_ptr<DistillerFactory> distiller_factory,
    scoped_ptr<DistillerPageFactory> distiller_page_factory)
    : store_(store.Pass()),
      content_store_(new InMemoryContentStore(kDefaultMaxNumCachedEntries)),
      distiller_factory_(distiller_factory.Pass()),
      distiller_page_factory_(distiller_page_factory.Pass()) {
}

DomDistillerService::~DomDistillerService() {
}

syncer::SyncableService* DomDistillerService::GetSyncableService() const {
  return store_->GetSyncableService();
}

scoped_ptr<DistillerPage> DomDistillerService::CreateDefaultDistillerPage() {
  return distiller_page_factory_->CreateDistillerPage().Pass();
}

scoped_ptr<DistillerPage>
DomDistillerService::CreateDefaultDistillerPageWithHandle(
    scoped_ptr<SourcePageHandle> handle) {
  return distiller_page_factory_->CreateDistillerPageWithHandle(handle.Pass())
      .Pass();
}

const std::string DomDistillerService::AddToList(
    const GURL& url,
    scoped_ptr<DistillerPage> distiller_page,
    const ArticleAvailableCallback& article_cb) {
  ArticleEntry entry;
  const bool is_already_added = store_->GetEntryByUrl(url, &entry);

  TaskTracker* task_tracker;
  if (is_already_added) {
    task_tracker = GetTaskTrackerForEntry(entry);
    if (task_tracker == NULL) {
      // Entry is in the store but there is no task tracker. This could
      // happen when distillation has already completed. For now just return
      // true.
      // TODO(shashishekhar): Change this to check if article is available,
      // An article may not be available for a variety of reasons, e.g.
      // distillation failure or blobs not available locally.
      base::MessageLoop::current()->PostTask(FROM_HERE,
                                             base::Bind(article_cb, true));
      return entry.entry_id();
    }
  } else {
    task_tracker = GetOrCreateTaskTrackerForUrl(url);
  }

  if (!article_cb.is_null()) {
    task_tracker->AddSaveCallback(
        base::Bind(&RunArticleAvailableCallback, article_cb));
  }

  if (!is_already_added) {
    task_tracker->AddSaveCallback(base::Bind(
        &DomDistillerService::AddDistilledPageToList, base::Unretained(this)));
    task_tracker->StartDistiller(distiller_factory_.get(),
                                 distiller_page.Pass());
    task_tracker->StartBlobFetcher();
  }

  return task_tracker->GetEntryId();
}

std::vector<ArticleEntry> DomDistillerService::GetEntries() const {
  return store_->GetEntries();
}

scoped_ptr<ArticleEntry> DomDistillerService::RemoveEntry(
    const std::string& entry_id) {
  scoped_ptr<ArticleEntry> entry(new ArticleEntry);
  entry->set_entry_id(entry_id);
  TaskTracker* task_tracker = GetTaskTrackerForEntry(*entry);
  if (task_tracker != NULL) {
    task_tracker->CancelSaveCallbacks();
  }

  if (!store_->GetEntryById(entry_id, entry.get())) {
    return scoped_ptr<ArticleEntry>();
  }

  if (store_->RemoveEntry(*entry)) {
    return entry.Pass();
  }
  return scoped_ptr<ArticleEntry>();
}

scoped_ptr<ViewerHandle> DomDistillerService::ViewEntry(
    ViewRequestDelegate* delegate,
    scoped_ptr<DistillerPage> distiller_page,
    const std::string& entry_id) {
  ArticleEntry entry;
  if (!store_->GetEntryById(entry_id, &entry)) {
    return scoped_ptr<ViewerHandle>();
  }

  TaskTracker* task_tracker = GetOrCreateTaskTrackerForEntry(entry);
  scoped_ptr<ViewerHandle> viewer_handle = task_tracker->AddViewer(delegate);
  task_tracker->StartDistiller(distiller_factory_.get(), distiller_page.Pass());
  task_tracker->StartBlobFetcher();

  return viewer_handle.Pass();
}

scoped_ptr<ViewerHandle> DomDistillerService::ViewUrl(
    ViewRequestDelegate* delegate,
    scoped_ptr<DistillerPage> distiller_page,
    const GURL& url) {
  if (!url.is_valid()) {
    return scoped_ptr<ViewerHandle>();
  }

  TaskTracker* task_tracker = GetOrCreateTaskTrackerForUrl(url);
  scoped_ptr<ViewerHandle> viewer_handle = task_tracker->AddViewer(delegate);
  task_tracker->StartDistiller(distiller_factory_.get(), distiller_page.Pass());
  task_tracker->StartBlobFetcher();

  return viewer_handle.Pass();
}

TaskTracker* DomDistillerService::GetOrCreateTaskTrackerForUrl(
    const GURL& url) {
  ArticleEntry entry;
  if (store_->GetEntryByUrl(url, &entry)) {
    return GetOrCreateTaskTrackerForEntry(entry);
  }

  for (TaskList::iterator it = tasks_.begin(); it != tasks_.end(); ++it) {
    if ((*it)->HasUrl(url)) {
      return *it;
    }
  }

  ArticleEntry skeleton_entry = CreateSkeletonEntryForUrl(url);
  TaskTracker* task_tracker = CreateTaskTracker(skeleton_entry);
  return task_tracker;
}

TaskTracker* DomDistillerService::GetTaskTrackerForEntry(
    const ArticleEntry& entry) const {
  const std::string& entry_id = entry.entry_id();
  for (TaskList::const_iterator it = tasks_.begin(); it != tasks_.end(); ++it) {
    if ((*it)->HasEntryId(entry_id)) {
      return *it;
    }
  }
  return NULL;
}

TaskTracker* DomDistillerService::GetOrCreateTaskTrackerForEntry(
    const ArticleEntry& entry) {
  TaskTracker* task_tracker = GetTaskTrackerForEntry(entry);
  if (task_tracker == NULL) {
    task_tracker = CreateTaskTracker(entry);
  }
  return task_tracker;
}

TaskTracker* DomDistillerService::CreateTaskTracker(const ArticleEntry& entry) {
  TaskTracker::CancelCallback cancel_callback =
      base::Bind(&DomDistillerService::CancelTask, base::Unretained(this));
  TaskTracker* tracker =
      new TaskTracker(entry, cancel_callback, content_store_.get());
  tasks_.push_back(tracker);
  return tracker;
}

void DomDistillerService::CancelTask(TaskTracker* task) {
  TaskList::iterator it = std::find(tasks_.begin(), tasks_.end(), task);
  if (it != tasks_.end()) {
    tasks_.weak_erase(it);
    base::MessageLoop::current()->DeleteSoon(FROM_HERE, task);
  }
}

void DomDistillerService::AddDistilledPageToList(
    const ArticleEntry& entry,
    const DistilledArticleProto* article_proto,
    bool distillation_succeeded) {
  DCHECK(IsEntryValid(entry));
  if (distillation_succeeded) {
    DCHECK(article_proto);
    DCHECK_GT(article_proto->pages_size(), 0);
    store_->AddEntry(entry);
    DCHECK_EQ(article_proto->pages_size(), entry.pages_size());
  }
}

void DomDistillerService::AddObserver(DomDistillerObserver* observer) {
  DCHECK(observer);
  store_->AddObserver(observer);
}

void DomDistillerService::RemoveObserver(DomDistillerObserver* observer) {
  DCHECK(observer);
  store_->RemoveObserver(observer);
}

}  // namespace dom_distiller
