// Copyright (c) 2011 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/download/save_package.h"

#include <algorithm>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/i18n/file_util_icu.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/stl_util-inl.h"
#include "base/string_piece.h"
#include "base/string_split.h"
#include "base/sys_string_conversions.h"
#include "base/task.h"
#include "base/threading/thread.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_item.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/download/download_shelf.h"
#include "chrome/browser/download/download_util.h"
#include "chrome/browser/download/save_file.h"
#include "chrome/browser/download/save_file_manager.h"
#include "chrome/browser/download/save_item.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/prefs/pref_member.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/browser/browser_thread.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/resource_dispatcher_host.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_service.h"
#include "content/common/notification_type.h"
#include "grit/generated_resources.h"
#include "net/base/io_buffer.h"
#include "net/base/mime_util.h"
#include "net/base/net_util.h"
#include "net/url_request/url_request_context.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPageSerializerClient.h"
#include "ui/base/l10n/l10n_util.h"
#include "net/url_request/url_request_context_getter.h"

using base::Time;
using WebKit::WebPageSerializerClient;

namespace {

// A counter for uniquely identifying each save package.
int g_save_package_id = 0;

// Default name which will be used when we can not get proper name from
// resource URL.
const char kDefaultSaveName[] = "saved_resource";

const FilePath::CharType kDefaultHtmlExtension[] =
#if defined(OS_WIN)
    FILE_PATH_LITERAL("htm");
#else
    FILE_PATH_LITERAL("html");
#endif

// Maximum number of file ordinal number. I think it's big enough for resolving
// name-conflict files which has same base file name.
const int32 kMaxFileOrdinalNumber = 9999;

// Maximum length for file path. Since Windows have MAX_PATH limitation for
// file path, we need to make sure length of file path of every saved file
// is less than MAX_PATH
#if defined(OS_WIN)
const uint32 kMaxFilePathLength = MAX_PATH - 1;
#elif defined(OS_POSIX)
const uint32 kMaxFilePathLength = PATH_MAX - 1;
#endif

// Maximum length for file ordinal number part. Since we only support the
// maximum 9999 for ordinal number, which means maximum file ordinal number part
// should be "(9998)", so the value is 6.
const uint32 kMaxFileOrdinalNumberPartLength = 6;

// If false, we don't prompt the user as to where to save the file.  This
// exists only for testing.
bool g_should_prompt_for_filename = true;

// Indexes used for specifying which element in the extensions dropdown
// the user chooses when picking a save type.
const int kSelectFileHtmlOnlyIndex = 1;
const int kSelectFileCompleteIndex = 2;

// Used for mapping between SavePackageType constants and the indexes above.
const SavePackage::SavePackageType kIndexToSaveType[] = {
  SavePackage::SAVE_TYPE_UNKNOWN,
  SavePackage::SAVE_AS_ONLY_HTML,
  SavePackage::SAVE_AS_COMPLETE_HTML,
};

// Used for mapping between the IDS_ string identifiers and the indexes above.
const int kIndexToIDS[] = {
  0, IDS_SAVE_PAGE_DESC_HTML_ONLY, IDS_SAVE_PAGE_DESC_COMPLETE,
};

int SavePackageTypeToIndex(SavePackage::SavePackageType type) {
  for (size_t i = 0; i < arraysize(kIndexToSaveType); ++i) {
    if (kIndexToSaveType[i] == type)
      return i;
  }
  NOTREACHED();
  return -1;
}

// Strip current ordinal number, if any. Should only be used on pure
// file names, i.e. those stripped of their extensions.
// TODO(estade): improve this to not choke on alternate encodings.
FilePath::StringType StripOrdinalNumber(
    const FilePath::StringType& pure_file_name) {
  FilePath::StringType::size_type r_paren_index =
      pure_file_name.rfind(FILE_PATH_LITERAL(')'));
  FilePath::StringType::size_type l_paren_index =
      pure_file_name.rfind(FILE_PATH_LITERAL('('));
  if (l_paren_index >= r_paren_index)
    return pure_file_name;

  for (FilePath::StringType::size_type i = l_paren_index + 1;
       i != r_paren_index; ++i) {
    if (!IsAsciiDigit(pure_file_name[i]))
      return pure_file_name;
  }

  return pure_file_name.substr(0, l_paren_index);
}

// Check whether we can save page as complete-HTML for the contents which
// have specified a MIME type. Now only contents which have the MIME type
// "text/html" can be saved as complete-HTML.
bool CanSaveAsComplete(const std::string& contents_mime_type) {
  return contents_mime_type == "text/html" ||
         contents_mime_type == "application/xhtml+xml";
}

}  // namespace

SavePackage::SavePackage(TabContents* tab_contents,
                         SavePackageType save_type,
                         const FilePath& file_full_path,
                         const FilePath& directory_full_path)
    : TabContentsObserver(tab_contents),
      file_manager_(NULL),
      download_(NULL),
      page_url_(GetUrlToBeSaved()),
      saved_main_file_path_(file_full_path),
      saved_main_directory_path_(directory_full_path),
      title_(tab_contents->GetTitle()),
      finished_(false),
      user_canceled_(false),
      disk_error_occurred_(false),
      save_type_(save_type),
      all_save_items_count_(0),
      wait_state_(INITIALIZE),
      tab_id_(tab_contents->GetRenderProcessHost()->id()),
      unique_id_(g_save_package_id++),
      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
  DCHECK(page_url_.is_valid());
  DCHECK(save_type_ == SAVE_AS_ONLY_HTML ||
         save_type_ == SAVE_AS_COMPLETE_HTML);
  DCHECK(!saved_main_file_path_.empty() &&
         saved_main_file_path_.value().length() <= kMaxFilePathLength);
  DCHECK(!saved_main_directory_path_.empty() &&
         saved_main_directory_path_.value().length() < kMaxFilePathLength);
  InternalInit();
}

SavePackage::SavePackage(TabContents* tab_contents)
    : TabContentsObserver(tab_contents),
      file_manager_(NULL),
      download_(NULL),
      page_url_(GetUrlToBeSaved()),
      title_(tab_contents->GetTitle()),
      finished_(false),
      user_canceled_(false),
      disk_error_occurred_(false),
      save_type_(SAVE_TYPE_UNKNOWN),
      all_save_items_count_(0),
      wait_state_(INITIALIZE),
      tab_id_(tab_contents->GetRenderProcessHost()->id()),
      unique_id_(g_save_package_id++),
      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
  DCHECK(page_url_.is_valid());
  InternalInit();
}

// This is for testing use. Set |finished_| as true because we don't want
// method Cancel to be be called in destructor in test mode.
// We also don't call InternalInit().
SavePackage::SavePackage(TabContents* tab_contents,
                         const FilePath& file_full_path,
                         const FilePath& directory_full_path)
    : TabContentsObserver(tab_contents),
      file_manager_(NULL),
      download_(NULL),
      saved_main_file_path_(file_full_path),
      saved_main_directory_path_(directory_full_path),
      finished_(true),
      user_canceled_(false),
      disk_error_occurred_(false),
      save_type_(SAVE_TYPE_UNKNOWN),
      all_save_items_count_(0),
      wait_state_(INITIALIZE),
      tab_id_(0),
      unique_id_(g_save_package_id++),
      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
}

SavePackage::~SavePackage() {
  // Stop receiving saving job's updates
  if (!finished_ && !canceled()) {
    // Unexpected quit.
    Cancel(true);
  }

  DCHECK(all_save_items_count_ == (waiting_item_queue_.size() +
                                   completed_count() +
                                   in_process_count()));
  // Free all SaveItems.
  while (!waiting_item_queue_.empty()) {
    // We still have some items which are waiting for start to save.
    SaveItem* save_item = waiting_item_queue_.front();
    waiting_item_queue_.pop();
    delete save_item;
  }

  STLDeleteValues(&saved_success_items_);
  STLDeleteValues(&in_progress_items_);
  STLDeleteValues(&saved_failed_items_);

  // The DownloadItem is owned by DownloadManager.
  download_ = NULL;

  file_manager_ = NULL;

  // If there's an outstanding save dialog, make sure it doesn't call us back
  // now that we're gone.
  if (select_file_dialog_.get())
    select_file_dialog_->ListenerDestroyed();
}

// Retrieves the URL to be saved from tab_contents_ variable.
GURL SavePackage::GetUrlToBeSaved() {
  // Instead of using tab_contents_.GetURL here, we use url()
  // (which is the "real" url of the page)
  // from the NavigationEntry because it reflects its' origin
  // rather than the displayed one (returned by GetURL) which may be
  // different (like having "view-source:" on the front).
  NavigationEntry* active_entry =
      tab_contents()->controller().GetActiveEntry();
  return active_entry->url();
}

// Cancel all in progress request, might be called by user or internal error.
void SavePackage::Cancel(bool user_action) {
  if (!canceled()) {
    if (user_action)
      user_canceled_ = true;
    else
      disk_error_occurred_ = true;
    Stop();
  }
}

// Init() can be called directly, or indirectly via GetSaveInfo(). In both
// cases, we need file_manager_ to be initialized, so we do this first.
void SavePackage::InternalInit() {
  ResourceDispatcherHost* rdh = g_browser_process->resource_dispatcher_host();
  if (!rdh) {
    NOTREACHED();
    return;
  }

  file_manager_ = rdh->save_file_manager();
  if (!file_manager_) {
    NOTREACHED();
    return;
  }
}

// Initialize the SavePackage.
bool SavePackage::Init() {
  // Set proper running state.
  if (wait_state_ != INITIALIZE)
    return false;

  wait_state_ = START_PROCESS;

  // Initialize the request context and resource dispatcher.
  Profile* profile = tab_contents()->profile();
  if (!profile) {
    NOTREACHED();
    return false;
  }

  request_context_getter_ = profile->GetRequestContext();

  // Create the fake DownloadItem and display the view.
  DownloadManager* download_manager =
      tab_contents()->profile()->GetDownloadManager();
  download_ = new DownloadItem(download_manager,
                               saved_main_file_path_,
                               page_url_,
                               profile->IsOffTheRecord());

  // Transfer the ownership to the download manager. We need the DownloadItem
  // to be alive as long as the Profile is alive.
  download_manager->SavePageAsDownloadStarted(download_);

  tab_contents()->OnStartDownload(download_);

  // Check save type and process the save page job.
  if (save_type_ == SAVE_AS_COMPLETE_HTML) {
    // Get directory
    DCHECK(!saved_main_directory_path_.empty());
    GetAllSavableResourceLinksForCurrentPage();
  } else {
    wait_state_ = NET_FILES;
    SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ?
        SaveFileCreateInfo::SAVE_FILE_FROM_FILE :
        SaveFileCreateInfo::SAVE_FILE_FROM_NET;
    SaveItem* save_item = new SaveItem(page_url_,
                                       GURL(),
                                       this,
                                       save_source);
    // Add this item to waiting list.
    waiting_item_queue_.push(save_item);
    all_save_items_count_ = 1;
    download_->set_total_bytes(1);

    DoSavingProcess();
  }

  return true;
}

// On POSIX, the length of |pure_file_name| + |file_name_ext| is further
// restricted by NAME_MAX. The maximum allowed path looks like:
// '/path/to/save_dir' + '/' + NAME_MAX.
uint32 SavePackage::GetMaxPathLengthForDirectory(const FilePath& base_dir) {
#if defined(OS_POSIX)
  return std::min(kMaxFilePathLength,
                  static_cast<uint32>(base_dir.value().length()) +
                  NAME_MAX + 1);
#else
  return kMaxFilePathLength;
#endif
}

// File name is considered being consist of pure file name, dot and file
// extension name. File name might has no dot and file extension, or has
// multiple dot inside file name. The dot, which separates the pure file
// name and file extension name, is last dot in the whole file name.
// This function is for making sure the length of specified file path is not
// great than the specified maximum length of file path and getting safe pure
// file name part if the input pure file name is too long.
// The parameter |dir_path| specifies directory part of the specified
// file path. The parameter |file_name_ext| specifies file extension
// name part of the specified file path (including start dot). The parameter
// |max_file_path_len| specifies maximum length of the specified file path.
// The parameter |pure_file_name| input pure file name part of the specified
// file path. If the length of specified file path is great than
// |max_file_path_len|, the |pure_file_name| will output new pure file name
// part for making sure the length of specified file path is less than
// specified maximum length of file path. Return false if the function can
// not get a safe pure file name, otherwise it returns true.
bool SavePackage::GetSafePureFileName(const FilePath& dir_path,
                                      const FilePath::StringType& file_name_ext,
                                      uint32 max_file_path_len,
                                      FilePath::StringType* pure_file_name) {
  DCHECK(!pure_file_name->empty());
  int available_length = static_cast<int>(max_file_path_len -
                                          dir_path.value().length() -
                                          file_name_ext.length());
  // Need an extra space for the separator.
  if (!file_util::EndsWithSeparator(dir_path))
    --available_length;

  // Plenty of room.
  if (static_cast<int>(pure_file_name->length()) <= available_length)
    return true;

  // Limited room. Truncate |pure_file_name| to fit.
  if (available_length > 0) {
    *pure_file_name = pure_file_name->substr(0, available_length);
    return true;
  }

  // Not enough room to even use a shortened |pure_file_name|.
  pure_file_name->clear();
  return false;
}

// Generate name for saving resource.
bool SavePackage::GenerateFileName(const std::string& disposition,
                                   const GURL& url,
                                   bool need_html_ext,
                                   FilePath::StringType* generated_name) {
  // TODO(jungshik): Figure out the referrer charset when having one
  // makes sense and pass it to GetSuggestedFilename.
  string16 suggested_name =
      net::GetSuggestedFilename(url, disposition, "",
                                ASCIIToUTF16(kDefaultSaveName));

  // TODO(evan): this code is totally wrong -- we should just generate
  // Unicode filenames and do all this encoding switching at the end.
  // However, I'm just shuffling wrong code around, at least not adding
  // to it.
#if defined(OS_WIN)
  FilePath file_path = FilePath(suggested_name);
#else
  FilePath file_path = FilePath(
      base::SysWideToNativeMB(UTF16ToWide(suggested_name)));
#endif

  DCHECK(!file_path.empty());
  FilePath::StringType pure_file_name =
      file_path.RemoveExtension().BaseName().value();
  FilePath::StringType file_name_ext = file_path.Extension();

  // If it is HTML resource, use ".htm{l,}" as its extension.
  if (need_html_ext) {
    file_name_ext = FILE_PATH_LITERAL(".");
    file_name_ext.append(kDefaultHtmlExtension);
  }

  // Need to make sure the suggested file name is not too long.
  uint32 max_path = GetMaxPathLengthForDirectory(saved_main_directory_path_);

  // Get safe pure file name.
  if (!GetSafePureFileName(saved_main_directory_path_, file_name_ext,
                           max_path, &pure_file_name))
    return false;

  FilePath::StringType file_name = pure_file_name + file_name_ext;

  // Check whether we already have same name.
  if (file_name_set_.find(file_name) == file_name_set_.end()) {
    file_name_set_.insert(file_name);
  } else {
    // Found same name, increase the ordinal number for the file name.
    FilePath::StringType base_file_name = StripOrdinalNumber(pure_file_name);

    // We need to make sure the length of base file name plus maximum ordinal
    // number path will be less than or equal to kMaxFilePathLength.
    if (!GetSafePureFileName(saved_main_directory_path_, file_name_ext,
        max_path - kMaxFileOrdinalNumberPartLength, &base_file_name))
      return false;

    // Prepare the new ordinal number.
    uint32 ordinal_number;
    FileNameCountMap::iterator it = file_name_count_map_.find(base_file_name);
    if (it == file_name_count_map_.end()) {
      // First base-name-conflict resolving, use 1 as initial ordinal number.
      file_name_count_map_[base_file_name] = 1;
      ordinal_number = 1;
    } else {
      // We have met same base-name conflict, use latest ordinal number.
      ordinal_number = it->second;
    }

    if (ordinal_number > (kMaxFileOrdinalNumber - 1)) {
      // Use a random file from temporary file.
      FilePath temp_file;
      file_util::CreateTemporaryFile(&temp_file);
      file_name = temp_file.RemoveExtension().BaseName().value();
      // Get safe pure file name.
      if (!GetSafePureFileName(saved_main_directory_path_,
                               FilePath::StringType(),
                               max_path, &file_name))
        return false;
    } else {
      for (int i = ordinal_number; i < kMaxFileOrdinalNumber; ++i) {
        FilePath::StringType new_name = base_file_name +
            StringPrintf(FILE_PATH_LITERAL("(%d)"), i) + file_name_ext;
        if (file_name_set_.find(new_name) == file_name_set_.end()) {
          // Resolved name conflict.
          file_name = new_name;
          file_name_count_map_[base_file_name] = ++i;
          break;
        }
      }
    }

    file_name_set_.insert(file_name);
  }

  DCHECK(!file_name.empty());
  generated_name->assign(file_name);

  return true;
}

// We have received a message from SaveFileManager about a new saving job. We
// create a SaveItem and store it in our in_progress list.
void SavePackage::StartSave(const SaveFileCreateInfo* info) {
  DCHECK(info && !info->url.is_empty());

  SaveUrlItemMap::iterator it = in_progress_items_.find(info->url.spec());
  if (it == in_progress_items_.end()) {
    // If not found, we must have cancel action.
    DCHECK(canceled());
    return;
  }
  SaveItem* save_item = it->second;

  DCHECK(!saved_main_file_path_.empty());

  save_item->SetSaveId(info->save_id);
  save_item->SetTotalBytes(info->total_bytes);

  // Determine the proper path for a saving job, by choosing either the default
  // save directory, or prompting the user.
  DCHECK(!save_item->has_final_name());
  if (info->url != page_url_) {
    FilePath::StringType generated_name;
    // For HTML resource file, make sure it will have .htm as extension name,
    // otherwise, when you open the saved page in Chrome again, download
    // file manager will treat it as downloadable resource, and download it
    // instead of opening it as HTML.
    bool need_html_ext =
        info->save_source == SaveFileCreateInfo::SAVE_FILE_FROM_DOM;
    if (!GenerateFileName(info->content_disposition,
                          GURL(info->url),
                          need_html_ext,
                          &generated_name)) {
      // We can not generate file name for this SaveItem, so we cancel the
      // saving page job if the save source is from serialized DOM data.
      // Otherwise, it means this SaveItem is sub-resource type, we treat it
      // as an error happened on saving. We can ignore this type error for
      // sub-resource links which will be resolved as absolute links instead
      // of local links in final saved contents.
      if (info->save_source == SaveFileCreateInfo::SAVE_FILE_FROM_DOM)
        Cancel(true);
      else
        SaveFinished(save_item->save_id(), 0, false);
      return;
    }

    // When saving page as only-HTML, we only have a SaveItem whose url
    // must be page_url_.
    DCHECK(save_type_ == SAVE_AS_COMPLETE_HTML);
    DCHECK(!saved_main_directory_path_.empty());

    // Now we get final name retrieved from GenerateFileName, we will use it
    // rename the SaveItem.
    FilePath final_name = saved_main_directory_path_.Append(generated_name);
    save_item->Rename(final_name);
  } else {
    // It is the main HTML file, use the name chosen by the user.
    save_item->Rename(saved_main_file_path_);
  }

  // If the save source is from file system, inform SaveFileManager to copy
  // corresponding file to the file path which this SaveItem specifies.
  if (info->save_source == SaveFileCreateInfo::SAVE_FILE_FROM_FILE) {
    BrowserThread::PostTask(
        BrowserThread::FILE, FROM_HERE,
        NewRunnableMethod(file_manager_,
                          &SaveFileManager::SaveLocalFile,
                          save_item->url(),
                          save_item->save_id(),
                          tab_id()));
    return;
  }

  // Check whether we begin to require serialized HTML data.
  if (save_type_ == SAVE_AS_COMPLETE_HTML && wait_state_ == HTML_DATA) {
    // Inform backend to serialize the all frames' DOM and send serialized
    // HTML data back.
    GetSerializedHtmlDataForCurrentPageWithLocalLinks();
  }
}

// Look up SaveItem by save id from in progress map.
SaveItem* SavePackage::LookupItemInProcessBySaveId(int32 save_id) {
  if (in_process_count()) {
    for (SaveUrlItemMap::iterator it = in_progress_items_.begin();
        it != in_progress_items_.end(); ++it) {
      SaveItem* save_item = it->second;
      DCHECK(save_item->state() == SaveItem::IN_PROGRESS);
      if (save_item->save_id() == save_id)
        return save_item;
    }
  }
  return NULL;
}

// Remove SaveItem from in progress map and put it to saved map.
void SavePackage::PutInProgressItemToSavedMap(SaveItem* save_item) {
  SaveUrlItemMap::iterator it = in_progress_items_.find(
      save_item->url().spec());
  DCHECK(it != in_progress_items_.end());
  DCHECK(save_item == it->second);
  in_progress_items_.erase(it);

  if (save_item->success()) {
    // Add it to saved_success_items_.
    DCHECK(saved_success_items_.find(save_item->save_id()) ==
           saved_success_items_.end());
    saved_success_items_[save_item->save_id()] = save_item;
  } else {
    // Add it to saved_failed_items_.
    DCHECK(saved_failed_items_.find(save_item->url().spec()) ==
           saved_failed_items_.end());
    saved_failed_items_[save_item->url().spec()] = save_item;
  }
}

// Called for updating saving state.
bool SavePackage::UpdateSaveProgress(int32 save_id,
                                     int64 size,
                                     bool write_success) {
  // Because we might have canceled this saving job before,
  // so we might not find corresponding SaveItem.
  SaveItem* save_item = LookupItemInProcessBySaveId(save_id);
  if (!save_item)
    return false;

  save_item->Update(size);

  // If we got disk error, cancel whole save page job.
  if (!write_success) {
    // Cancel job with reason of disk error.
    Cancel(false);
  }
  return true;
}

// Stop all page saving jobs that are in progress and instruct the file thread
// to delete all saved  files.
void SavePackage::Stop() {
  // If we haven't moved out of the initial state, there's nothing to cancel and
  // there won't be valid pointers for file_manager_ or download_.
  if (wait_state_ == INITIALIZE)
    return;

  // When stopping, if it still has some items in in_progress, cancel them.
  DCHECK(canceled());
  if (in_process_count()) {
    SaveUrlItemMap::iterator it = in_progress_items_.begin();
    for (; it != in_progress_items_.end(); ++it) {
      SaveItem* save_item = it->second;
      DCHECK(save_item->state() == SaveItem::IN_PROGRESS);
      save_item->Cancel();
    }
    // Remove all in progress item to saved map. For failed items, they will
    // be put into saved_failed_items_, for successful item, they will be put
    // into saved_success_items_.
    while (in_process_count())
      PutInProgressItemToSavedMap(in_progress_items_.begin()->second);
  }

  // This vector contains the save ids of the save files which SaveFileManager
  // needs to remove from its save_file_map_.
  SaveIDList save_ids;
  for (SavedItemMap::iterator it = saved_success_items_.begin();
      it != saved_success_items_.end(); ++it)
    save_ids.push_back(it->first);
  for (SaveUrlItemMap::iterator it = saved_failed_items_.begin();
      it != saved_failed_items_.end(); ++it)
    save_ids.push_back(it->second->save_id());

  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(file_manager_,
                        &SaveFileManager::RemoveSavedFileFromFileMap,
                        save_ids));

  finished_ = true;
  wait_state_ = FAILED;

  // Inform the DownloadItem we have canceled whole save page job.
  download_->Cancel(false);
}

void SavePackage::CheckFinish() {
  if (in_process_count() || finished_)
    return;

  FilePath dir = (save_type_ == SAVE_AS_COMPLETE_HTML &&
                  saved_success_items_.size() > 1) ?
                  saved_main_directory_path_ : FilePath();

  // This vector contains the final names of all the successfully saved files
  // along with their save ids. It will be passed to SaveFileManager to do the
  // renaming job.
  FinalNameList final_names;
  for (SavedItemMap::iterator it = saved_success_items_.begin();
      it != saved_success_items_.end(); ++it)
    final_names.push_back(std::make_pair(it->first,
                                         it->second->full_path()));

  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(file_manager_,
                        &SaveFileManager::RenameAllFiles,
                        final_names,
                        dir,
                        tab_contents()->GetRenderProcessHost()->id(),
                        tab_contents()->render_view_host()->routing_id(),
                        id()));
}

// Successfully finished all items of this SavePackage.
void SavePackage::Finish() {
  // User may cancel the job when we're moving files to the final directory.
  if (canceled())
    return;

  wait_state_ = SUCCESSFUL;
  finished_ = true;

  // This vector contains the save ids of the save files which SaveFileManager
  // needs to remove from its save_file_map_.
  SaveIDList save_ids;
  for (SaveUrlItemMap::iterator it = saved_failed_items_.begin();
       it != saved_failed_items_.end(); ++it)
    save_ids.push_back(it->second->save_id());

  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(file_manager_,
                        &SaveFileManager::RemoveSavedFileFromFileMap,
                        save_ids));

  download_->OnAllDataSaved(all_save_items_count_);
  download_->MarkAsComplete();

  NotificationService::current()->Notify(
      NotificationType::SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
      Source<SavePackage>(this),
      Details<GURL>(&page_url_));
}

// Called for updating end state.
void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) {
  // Because we might have canceled this saving job before,
  // so we might not find corresponding SaveItem. Just ignore it.
  SaveItem* save_item = LookupItemInProcessBySaveId(save_id);
  if (!save_item)
    return;

  // Let SaveItem set end state.
  save_item->Finish(size, is_success);
  // Remove the associated save id and SavePackage.
  file_manager_->RemoveSaveFile(save_id, save_item->url(), this);

  PutInProgressItemToSavedMap(save_item);

  // Inform the DownloadItem to update UI.
  // We use the received bytes as number of saved files.
  download_->Update(completed_count());

  if (save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM &&
      save_item->url() == page_url_ && !save_item->received_bytes()) {
    // If size of main HTML page is 0, treat it as disk error.
    Cancel(false);
    return;
  }

  if (canceled()) {
    DCHECK(finished_);
    return;
  }

  // Continue processing the save page job.
  DoSavingProcess();

  // Check whether we can successfully finish whole job.
  CheckFinish();
}

// Sometimes, the net io will only call SaveFileManager::SaveFinished with
// save id -1 when it encounters error. Since in this case, save id will be
// -1, so we can only use URL to find which SaveItem is associated with
// this error.
// Saving an item failed. If it's a sub-resource, ignore it. If the error comes
// from serializing HTML data, then cancel saving page.
void SavePackage::SaveFailed(const GURL& save_url) {
  SaveUrlItemMap::iterator it = in_progress_items_.find(save_url.spec());
  if (it == in_progress_items_.end()) {
    NOTREACHED();  // Should not exist!
    return;
  }
  SaveItem* save_item = it->second;

  save_item->Finish(0, false);

  PutInProgressItemToSavedMap(save_item);

  // Inform the DownloadItem to update UI.
  // We use the received bytes as number of saved files.
  download_->Update(completed_count());

  if (save_type_ == SAVE_AS_ONLY_HTML ||
      save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM) {
    // We got error when saving page. Treat it as disk error.
    Cancel(true);
  }

  if (canceled()) {
    DCHECK(finished_);
    return;
  }

  // Continue processing the save page job.
  DoSavingProcess();

  CheckFinish();
}

void SavePackage::SaveCanceled(SaveItem* save_item) {
  // Call the RemoveSaveFile in UI thread.
  file_manager_->RemoveSaveFile(save_item->save_id(),
                                save_item->url(),
                                this);
  if (save_item->save_id() != -1)
    BrowserThread::PostTask(
        BrowserThread::FILE, FROM_HERE,
        NewRunnableMethod(file_manager_,
                          &SaveFileManager::CancelSave,
                          save_item->save_id()));
}

// Initiate a saving job of a specific URL. We send the request to
// SaveFileManager, which will dispatch it to different approach according to
// the save source. Parameter process_all_remaining_items indicates whether
// we need to save all remaining items.
void SavePackage::SaveNextFile(bool process_all_remaining_items) {
  DCHECK(tab_contents());
  DCHECK(waiting_item_queue_.size());

  do {
    // Pop SaveItem from waiting list.
    SaveItem* save_item = waiting_item_queue_.front();
    waiting_item_queue_.pop();

    // Add the item to in_progress_items_.
    SaveUrlItemMap::iterator it = in_progress_items_.find(
        save_item->url().spec());
    DCHECK(it == in_progress_items_.end());
    in_progress_items_[save_item->url().spec()] = save_item;
    save_item->Start();
    file_manager_->SaveURL(save_item->url(),
                           save_item->referrer(),
                           tab_contents()->GetRenderProcessHost()->id(),
                           routing_id(),
                           save_item->save_source(),
                           save_item->full_path(),
                           request_context_getter_.get(),
                           this);
  } while (process_all_remaining_items && waiting_item_queue_.size());
}


// Open download page in windows explorer on file thread, to avoid blocking the
// user interface.
void SavePackage::ShowDownloadInShell() {
  DCHECK(file_manager_);
  DCHECK(finished_ && !canceled() && !saved_main_file_path_.empty());
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
#if defined(OS_MACOSX)
  // Mac OS X requires opening downloads on the UI thread.
  platform_util::ShowItemInFolder(saved_main_file_path_);
#else
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(file_manager_,
                        &SaveFileManager::OnShowSavedFileInShell,
                        saved_main_file_path_));
#endif
}

// Calculate the percentage of whole save page job.
int SavePackage::PercentComplete() {
  if (!all_save_items_count_)
    return 0;
  else if (!in_process_count())
    return 100;
  else
    return completed_count() / all_save_items_count_;
}

// Continue processing the save page job after one SaveItem has been
// finished.
void SavePackage::DoSavingProcess() {
  if (save_type_ == SAVE_AS_COMPLETE_HTML) {
    // We guarantee that images and JavaScripts must be downloaded first.
    // So when finishing all those sub-resources, we will know which
    // sub-resource's link can be replaced with local file path, which
    // sub-resource's link need to be replaced with absolute URL which
    // point to its internet address because it got error when saving its data.
    SaveItem* save_item = NULL;
    // Start a new SaveItem job if we still have job in waiting queue.
    if (waiting_item_queue_.size()) {
      DCHECK(wait_state_ == NET_FILES);
      save_item = waiting_item_queue_.front();
      if (save_item->save_source() != SaveFileCreateInfo::SAVE_FILE_FROM_DOM) {
        SaveNextFile(false);
      } else if (!in_process_count()) {
        // If there is no in-process SaveItem, it means all sub-resources
        // have been processed. Now we need to start serializing HTML DOM
        // for the current page to get the generated HTML data.
        wait_state_ = HTML_DATA;
        // All non-HTML resources have been finished, start all remaining
        // HTML files.
        SaveNextFile(true);
      }
    } else if (in_process_count()) {
      // Continue asking for HTML data.
      DCHECK(wait_state_ == HTML_DATA);
    }
  } else {
    // Save as HTML only.
    DCHECK(wait_state_ == NET_FILES);
    DCHECK(save_type_ == SAVE_AS_ONLY_HTML);
    if (waiting_item_queue_.size()) {
      DCHECK(all_save_items_count_ == waiting_item_queue_.size());
      SaveNextFile(false);
    }
  }
}

bool SavePackage::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(SavePackage, message)
    IPC_MESSAGE_HANDLER(ViewHostMsg_SendCurrentPageAllSavableResourceLinks,
                        OnReceivedSavableResourceLinksForCurrentPage)
    IPC_MESSAGE_HANDLER(ViewHostMsg_SendSerializedHtmlData,
                        OnReceivedSerializedHtmlData)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

// After finishing all SaveItems which need to get data from net.
// We collect all URLs which have local storage and send the
// map:(originalURL:currentLocalPath) to render process (backend).
// Then render process will serialize DOM and send data to us.
void SavePackage::GetSerializedHtmlDataForCurrentPageWithLocalLinks() {
  if (wait_state_ != HTML_DATA)
    return;
  std::vector<GURL> saved_links;
  std::vector<FilePath> saved_file_paths;
  int successful_started_items_count = 0;

  // Collect all saved items which have local storage.
  // First collect the status of all the resource files and check whether they
  // have created local files although they have not been completely saved.
  // If yes, the file can be saved. Otherwise, there is a disk error, so we
  // need to cancel the page saving job.
  for (SaveUrlItemMap::iterator it = in_progress_items_.begin();
       it != in_progress_items_.end(); ++it) {
    DCHECK(it->second->save_source() ==
           SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
    if (it->second->has_final_name())
      successful_started_items_count++;
    saved_links.push_back(it->second->url());
    saved_file_paths.push_back(it->second->file_name());
  }

  // If not all file of HTML resource have been started, then wait.
  if (successful_started_items_count != in_process_count())
    return;

  // Collect all saved success items.
  for (SavedItemMap::iterator it = saved_success_items_.begin();
       it != saved_success_items_.end(); ++it) {
    DCHECK(it->second->has_final_name());
    saved_links.push_back(it->second->url());
    saved_file_paths.push_back(it->second->file_name());
  }

  // Get the relative directory name.
  FilePath relative_dir_name = saved_main_directory_path_.BaseName();

  tab_contents()->render_view_host()->
      GetSerializedHtmlDataForCurrentPageWithLocalLinks(
      saved_links, saved_file_paths, relative_dir_name);
}

// Process the serialized HTML content data of a specified web page
// retrieved from render process.
void SavePackage::OnReceivedSerializedHtmlData(const GURL& frame_url,
                                               const std::string& data,
                                               int32 status) {
  WebPageSerializerClient::PageSerializationStatus flag =
      static_cast<WebPageSerializerClient::PageSerializationStatus>(status);
  // Check current state.
  if (wait_state_ != HTML_DATA)
    return;

  int id = tab_id();
  // If the all frames are finished saving, we need to close the
  // remaining SaveItems.
  if (flag == WebPageSerializerClient::AllFramesAreFinished) {
    for (SaveUrlItemMap::iterator it = in_progress_items_.begin();
         it != in_progress_items_.end(); ++it) {
      VLOG(20) << " " << __FUNCTION__ << "()"
               << " save_id = " << it->second->save_id()
               << " url = \"" << it->second->url().spec() << "\"";
      BrowserThread::PostTask(
          BrowserThread::FILE, FROM_HERE,
          NewRunnableMethod(file_manager_,
                            &SaveFileManager::SaveFinished,
                            it->second->save_id(),
                            it->second->url(),
                            id,
                            true));
    }
    return;
  }

  SaveUrlItemMap::iterator it = in_progress_items_.find(frame_url.spec());
  if (it == in_progress_items_.end())
    return;
  SaveItem* save_item = it->second;
  DCHECK(save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM);

  if (!data.empty()) {
    // Prepare buffer for saving HTML data.
    scoped_refptr<net::IOBuffer> new_data(new net::IOBuffer(data.size()));
    memcpy(new_data->data(), data.data(), data.size());

    // Call write file functionality in file thread.
    BrowserThread::PostTask(
        BrowserThread::FILE, FROM_HERE,
        NewRunnableMethod(file_manager_,
                          &SaveFileManager::UpdateSaveProgress,
                          save_item->save_id(),
                          new_data,
                          static_cast<int>(data.size())));
  }

  // Current frame is completed saving, call finish in file thread.
  if (flag == WebPageSerializerClient::CurrentFrameIsFinished) {
    VLOG(20) << " " << __FUNCTION__ << "()"
             << " save_id = " << save_item->save_id()
             << " url = \"" << save_item->url().spec() << "\"";
    BrowserThread::PostTask(
        BrowserThread::FILE, FROM_HERE,
        NewRunnableMethod(file_manager_,
                          &SaveFileManager::SaveFinished,
                          save_item->save_id(),
                          save_item->url(),
                          id,
                          true));
  }
}

// Ask for all savable resource links from backend, include main frame and
// sub-frame.
void SavePackage::GetAllSavableResourceLinksForCurrentPage() {
  if (wait_state_ != START_PROCESS)
    return;

  wait_state_ = RESOURCES_LIST;
  tab_contents()->render_view_host()->
      GetAllSavableResourceLinksForCurrentPage(page_url_);
}

// Give backend the lists which contain all resource links that have local
// storage, after which, render process will serialize DOM for generating
// HTML data.
void SavePackage::OnReceivedSavableResourceLinksForCurrentPage(
    const std::vector<GURL>& resources_list,
    const std::vector<GURL>& referrers_list,
    const std::vector<GURL>& frames_list) {
  if (wait_state_ != RESOURCES_LIST)
    return;

  DCHECK(resources_list.size() == referrers_list.size());
  all_save_items_count_ = static_cast<int>(resources_list.size()) +
                           static_cast<int>(frames_list.size());

  // We use total bytes as the total number of files we want to save.
  download_->set_total_bytes(all_save_items_count_);

  if (all_save_items_count_) {
    // Put all sub-resources to wait list.
    for (int i = 0; i < static_cast<int>(resources_list.size()); ++i) {
      const GURL& u = resources_list[i];
      DCHECK(u.is_valid());
      SaveFileCreateInfo::SaveFileSource save_source = u.SchemeIsFile() ?
          SaveFileCreateInfo::SAVE_FILE_FROM_FILE :
          SaveFileCreateInfo::SAVE_FILE_FROM_NET;
      SaveItem* save_item = new SaveItem(u, referrers_list[i],
                                         this, save_source);
      waiting_item_queue_.push(save_item);
    }
    // Put all HTML resources to wait list.
    for (int i = 0; i < static_cast<int>(frames_list.size()); ++i) {
      const GURL& u = frames_list[i];
      DCHECK(u.is_valid());
      SaveItem* save_item = new SaveItem(u, GURL(),
          this, SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
      waiting_item_queue_.push(save_item);
    }
    wait_state_ = NET_FILES;
    DoSavingProcess();
  } else {
    // No resource files need to be saved, treat it as user cancel.
    Cancel(true);
  }
}

void SavePackage::SetShouldPromptUser(bool should_prompt) {
  g_should_prompt_for_filename = should_prompt;
}

FilePath SavePackage::GetSuggestedNameForSaveAs(
    bool can_save_as_complete,
    const std::string& contents_mime_type) {
  FilePath name_with_proper_ext =
      FilePath::FromWStringHack(UTF16ToWideHack(title_));

  // If the page's title matches its URL, use the URL. Try to use the last path
  // component or if there is none, the domain as the file name.
  // Normally we want to base the filename on the page title, or if it doesn't
  // exist, on the URL. It's not easy to tell if the page has no title, because
  // if the page has no title, TabContents::GetTitle() will return the page's
  // URL (adjusted for display purposes). Therefore, we convert the "title"
  // back to a URL, and if it matches the original page URL, we know the page
  // had no title (or had a title equal to its URL, which is fine to treat
  // similarly).
  GURL fixed_up_title_url =
      URLFixerUpper::FixupURL(UTF16ToUTF8(title_), std::string());

  if (page_url_ == fixed_up_title_url) {
    std::string url_path;
    std::vector<std::string> url_parts;
    base::SplitString(page_url_.path(), '/', &url_parts);
    if (!url_parts.empty()) {
      for (int i = static_cast<int>(url_parts.size()) - 1; i >= 0; --i) {
        url_path = url_parts[i];
        if (!url_path.empty())
          break;
      }
    }
    if (url_path.empty())
      url_path = page_url_.host();
    name_with_proper_ext = FilePath::FromWStringHack(UTF8ToWide(url_path));
  }

  // Ask user for getting final saving name.
  name_with_proper_ext = EnsureMimeExtension(name_with_proper_ext,
                                             contents_mime_type);
  // Adjust extension for complete types.
  if (can_save_as_complete)
    name_with_proper_ext = EnsureHtmlExtension(name_with_proper_ext);

  FilePath::StringType file_name = name_with_proper_ext.value();
  file_util::ReplaceIllegalCharactersInPath(&file_name, ' ');
  return FilePath(file_name);
}

FilePath SavePackage::EnsureHtmlExtension(const FilePath& name) {
  // If the file name doesn't have an extension suitable for HTML files,
  // append one.
  FilePath::StringType ext = name.Extension();
  if (!ext.empty())
    ext.erase(ext.begin());  // Erase preceding '.'.
  std::string mime_type;
  if (!net::GetMimeTypeFromExtension(ext, &mime_type) ||
      !CanSaveAsComplete(mime_type)) {
    return FilePath(name.value() + FILE_PATH_LITERAL(".") +
                    kDefaultHtmlExtension);
  }
  return name;
}

FilePath SavePackage::EnsureMimeExtension(const FilePath& name,
    const std::string& contents_mime_type) {
  // Start extension at 1 to skip over period if non-empty.
  FilePath::StringType ext = name.Extension().length() ?
      name.Extension().substr(1) : name.Extension();
  FilePath::StringType suggested_extension =
      ExtensionForMimeType(contents_mime_type);
  std::string mime_type;
  if (!suggested_extension.empty() &&
      (!net::GetMimeTypeFromExtension(ext, &mime_type) ||
      !IsSavableContents(mime_type))) {
    // Extension is absent or needs to be updated.
    return FilePath(name.value() + FILE_PATH_LITERAL(".") +
                    suggested_extension);
  }
  return name;
}

const FilePath::CharType* SavePackage::ExtensionForMimeType(
    const std::string& contents_mime_type) {
  static const struct {
    const FilePath::CharType *mime_type;
    const FilePath::CharType *suggested_extension;
  } extensions[] = {
    { FILE_PATH_LITERAL("text/html"), kDefaultHtmlExtension },
    { FILE_PATH_LITERAL("text/xml"), FILE_PATH_LITERAL("xml") },
    { FILE_PATH_LITERAL("application/xhtml+xml"), FILE_PATH_LITERAL("xhtml") },
    { FILE_PATH_LITERAL("text/plain"), FILE_PATH_LITERAL("txt") },
    { FILE_PATH_LITERAL("text/css"), FILE_PATH_LITERAL("css") },
  };
#if defined(OS_POSIX)
  FilePath::StringType mime_type(contents_mime_type);
#elif defined(OS_WIN)
  FilePath::StringType mime_type(UTF8ToWide(contents_mime_type));
#endif  // OS_WIN
  for (uint32 i = 0; i < ARRAYSIZE_UNSAFE(extensions); ++i) {
    if (mime_type == extensions[i].mime_type)
      return extensions[i].suggested_extension;
  }
  return FILE_PATH_LITERAL("");
}



// static.
// Check whether the preference has the preferred directory for saving file. If
// not, initialize it with default directory.
FilePath SavePackage::GetSaveDirPreference(PrefService* prefs) {
  DCHECK(prefs);

  if (!prefs->FindPreference(prefs::kSaveFileDefaultDirectory)) {
    DCHECK(prefs->FindPreference(prefs::kDownloadDefaultDirectory));
    FilePath default_save_path = prefs->GetFilePath(
        prefs::kDownloadDefaultDirectory);
    prefs->RegisterFilePathPref(prefs::kSaveFileDefaultDirectory,
                                default_save_path);
  }

  // Get the directory from preference.
  FilePath save_file_path = prefs->GetFilePath(
      prefs::kSaveFileDefaultDirectory);
  DCHECK(!save_file_path.empty());

  return save_file_path;
}

void SavePackage::GetSaveInfo() {
  // Can't use tab_contents_ in the file thread, so get the data that we need
  // before calling to it.
  PrefService* prefs = tab_contents()->profile()->GetPrefs();
  FilePath website_save_dir = GetSaveDirPreference(prefs);
  FilePath download_save_dir = prefs->GetFilePath(
      prefs::kDownloadDefaultDirectory);
  std::string mime_type = tab_contents()->contents_mime_type();

  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(this, &SavePackage::CreateDirectoryOnFileThread,
          website_save_dir, download_save_dir, mime_type));
}

void SavePackage::CreateDirectoryOnFileThread(
    const FilePath& website_save_dir,
    const FilePath& download_save_dir,
    const std::string& mime_type) {
  FilePath save_dir;
  // If the default html/websites save folder doesn't exist...
  if (!file_util::DirectoryExists(website_save_dir)) {
    // If the default download dir doesn't exist, create it.
    if (!file_util::DirectoryExists(download_save_dir))
      file_util::CreateDirectory(download_save_dir);
    save_dir = download_save_dir;
  } else {
    // If it does exist, use the default save dir param.
    save_dir = website_save_dir;
  }

  bool can_save_as_complete = CanSaveAsComplete(mime_type);
  FilePath suggested_filename = GetSuggestedNameForSaveAs(can_save_as_complete,
                                                          mime_type);
  FilePath::StringType pure_file_name =
      suggested_filename.RemoveExtension().BaseName().value();
  FilePath::StringType file_name_ext = suggested_filename.Extension();

  // Need to make sure the suggested file name is not too long.
  uint32 max_path = GetMaxPathLengthForDirectory(save_dir);

  if (GetSafePureFileName(save_dir, file_name_ext, max_path, &pure_file_name)) {
    save_dir = save_dir.Append(pure_file_name + file_name_ext);
  } else {
    // Cannot create a shorter filename. This will cause the save as operation
    // to fail unless the user pick a shorter name. Continuing even though it
    // will fail because returning means no save as popup for the user, which
    // is even more confusing. This case should be rare though.
    save_dir = save_dir.Append(suggested_filename);
  }

  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      NewRunnableMethod(this, &SavePackage::ContinueGetSaveInfo, save_dir,
                        can_save_as_complete));
}

void SavePackage::ContinueGetSaveInfo(const FilePath& suggested_path,
                                      bool can_save_as_complete) {
  // The TabContents which owns this SavePackage may have disappeared during
  // the UI->FILE->UI thread hop of
  // GetSaveInfo->CreateDirectoryOnFileThread->ContinueGetSaveInfo.
  if (!tab_contents())
    return;
  DownloadPrefs* download_prefs =
      tab_contents()->profile()->GetDownloadManager()->download_prefs();
  int file_type_index =
      SavePackageTypeToIndex(
          static_cast<SavePackageType>(download_prefs->save_file_type()));

  SelectFileDialog::FileTypeInfo file_type_info;
  FilePath::StringType default_extension;

  // If the contents can not be saved as complete-HTML, do not show the
  // file filters.
  if (can_save_as_complete) {
    bool add_extra_extension = false;
    FilePath::StringType extra_extension;
    if (!suggested_path.Extension().empty() &&
        suggested_path.Extension().compare(FILE_PATH_LITERAL("htm")) &&
        suggested_path.Extension().compare(FILE_PATH_LITERAL("html"))) {
      add_extra_extension = true;
      extra_extension = suggested_path.Extension().substr(1);
    }

    file_type_info.extensions.resize(2);
    file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
        FILE_PATH_LITERAL("htm"));
    file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
        FILE_PATH_LITERAL("html"));

    if (add_extra_extension) {
      file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
          extra_extension);
    }

    file_type_info.extension_description_overrides.push_back(
        l10n_util::GetStringUTF16(kIndexToIDS[kSelectFileCompleteIndex - 1]));
    file_type_info.extensions[kSelectFileCompleteIndex - 1].push_back(
        FILE_PATH_LITERAL("htm"));
    file_type_info.extensions[kSelectFileCompleteIndex - 1].push_back(
        FILE_PATH_LITERAL("html"));

    if (add_extra_extension) {
      file_type_info.extensions[kSelectFileCompleteIndex - 1].push_back(
          extra_extension);
    }

    file_type_info.extension_description_overrides.push_back(
        l10n_util::GetStringUTF16(kIndexToIDS[kSelectFileCompleteIndex]));
    file_type_info.include_all_files = false;
    default_extension = kDefaultHtmlExtension;
  } else {
    file_type_info.extensions.resize(1);
    file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
        suggested_path.Extension());

    if (!file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1][0].empty()) {
      // Drop the .
      file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1][0].erase(0, 1);
    }

    file_type_info.include_all_files = true;
    file_type_index = 1;
  }

  if (g_should_prompt_for_filename) {
    if (!select_file_dialog_.get())
      select_file_dialog_ = SelectFileDialog::Create(this);
    select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE,
                                    string16(),
                                    suggested_path,
                                    &file_type_info,
                                    file_type_index,
                                    default_extension,
                                    tab_contents(),
                                    platform_util::GetTopLevel(
                                        tab_contents()->GetNativeView()),
                                    NULL);
  } else {
    // Just use 'suggested_path' instead of opening the dialog prompt.
    ContinueSave(suggested_path, file_type_index);
  }
}

// Called after the save file dialog box returns.
void SavePackage::ContinueSave(const FilePath& final_name,
                               int index) {
  // Ensure the filename is safe.
  saved_main_file_path_ = final_name;
  download_util::GenerateSafeFileName(tab_contents()->contents_mime_type(),
                                      &saved_main_file_path_);

  // The option index is not zero-based.
  DCHECK(index >= kSelectFileHtmlOnlyIndex &&
         index <= kSelectFileCompleteIndex);

  saved_main_directory_path_ = saved_main_file_path_.DirName();

  PrefService* prefs = tab_contents()->profile()->GetPrefs();
  StringPrefMember save_file_path;
  save_file_path.Init(prefs::kSaveFileDefaultDirectory, prefs, NULL);
#if defined(OS_POSIX)
  std::string path_string = saved_main_directory_path_.value();
#elif defined(OS_WIN)
  std::string path_string = WideToUTF8(saved_main_directory_path_.value());
#endif
  // If user change the default saving directory, we will remember it just
  // like IE and FireFox.
  if (!tab_contents()->profile()->IsOffTheRecord() &&
      save_file_path.GetValue() != path_string) {
    save_file_path.SetValue(path_string);
  }

  save_type_ = kIndexToSaveType[index];

  prefs->SetInteger(prefs::kSaveFileType, save_type_);

  if (save_type_ == SavePackage::SAVE_AS_COMPLETE_HTML) {
    // Make new directory for saving complete file.
    saved_main_directory_path_ = saved_main_directory_path_.Append(
        saved_main_file_path_.RemoveExtension().BaseName().value() +
        FILE_PATH_LITERAL("_files"));
  }

  Init();
}

// Static
bool SavePackage::IsSavableURL(const GURL& url) {
  for (int i = 0; chrome::kSavableSchemes[i] != NULL; ++i) {
    if (url.SchemeIs(chrome::kSavableSchemes[i])) {
      return true;
    }
  }
  return false;
}

// Static
bool SavePackage::IsSavableContents(const std::string& contents_mime_type) {
  // WebKit creates Document object when MIME type is application/xhtml+xml,
  // so we also support this MIME type.
  return contents_mime_type == "text/html" ||
         contents_mime_type == "text/xml" ||
         contents_mime_type == "application/xhtml+xml" ||
         contents_mime_type == "text/plain" ||
         contents_mime_type == "text/css" ||
         net::IsSupportedJavascriptMimeType(contents_mime_type.c_str());
}

// SelectFileDialog::Listener interface.
void SavePackage::FileSelected(const FilePath& path,
                               int index, void* params) {
  ContinueSave(path, index);
}

void SavePackage::FileSelectionCanceled(void* params) {
}
