// Copyright (c) 2012 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/chromeos/extensions/file_manager/zip_file_creator.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_util_proxy.h"
#include "base/memory/scoped_handle.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/threading/sequenced_worker_pool.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_utility_messages.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/utility_process_host.h"
#include "grit/generated_resources.h"

using content::BrowserThread;
using content::UtilityProcessHost;

namespace file_manager {

ZipFileCreator::ZipFileCreator(
    Observer* observer,
    const base::FilePath& src_dir,
    const std::vector<base::FilePath>& src_relative_paths,
    const base::FilePath& dest_file)
    : thread_identifier_(BrowserThread::ID_COUNT),
      observer_(observer),
      src_dir_(src_dir),
      src_relative_paths_(src_relative_paths),
      dest_file_(dest_file),
      got_response_(false) {
}

void ZipFileCreator::Start() {
  CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_identifier_));
  BrowserThread::GetBlockingPool()->PostTask(
      FROM_HERE,
      base::Bind(&ZipFileCreator::OpenFileHandleOnBlockingThreadPool, this));
}

ZipFileCreator::~ZipFileCreator() {
}

bool ZipFileCreator::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(ZipFileCreator, message)
    IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_CreateZipFile_Succeeded,
                        OnCreateZipFileSucceeded)
    IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_CreateZipFile_Failed,
                        OnCreateZipFileFailed)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void ZipFileCreator::OnProcessCrashed(int exit_code) {
  // Don't report crashes if they happen after we got a response.
  if (got_response_)
    return;

  // Utility process crashed while trying to create the zip file.
  ReportDone(false);
}

void ZipFileCreator::OpenFileHandleOnBlockingThreadPool() {
  // Create the destination zip file only if it does not already exist.
  int flags = base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE;
  base::PlatformFileError error_code = base::PLATFORM_FILE_OK;
  base::PlatformFile dest_file =
      base::CreatePlatformFile(dest_file_, flags, NULL, &error_code);

  if (error_code != base::PLATFORM_FILE_OK) {
    LOG(ERROR) << "Failed to create dest zip file " << dest_file_.value();

    BrowserThread::GetMessageLoopProxyForThread(thread_identifier_)->PostTask(
        FROM_HERE,
        base::Bind(&ZipFileCreator::ReportDone, this, false));
    return;
  }

  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&ZipFileCreator::StartProcessOnIOThread, this, dest_file));
}

void ZipFileCreator::StartProcessOnIOThread(base::PlatformFile dest_file) {
  base::FileDescriptor dest_fd;
  dest_fd.fd = dest_file;
  dest_fd.auto_close = true;

  UtilityProcessHost* host = UtilityProcessHost::Create(
      this,
      BrowserThread::GetMessageLoopProxyForThread(thread_identifier_).get());
  host->Send(new ChromeUtilityMsg_CreateZipFile(src_dir_, src_relative_paths_,
                                                dest_fd));
}

void ZipFileCreator::OnCreateZipFileSucceeded() {
  ReportDone(true);
}

void ZipFileCreator::OnCreateZipFileFailed() {
  ReportDone(false);
}

void ZipFileCreator::ReportDone(bool success) {
  // Skip check for unittests.
  if (thread_identifier_ != BrowserThread::ID_COUNT)
    DCHECK(BrowserThread::CurrentlyOn(thread_identifier_));

  // Guard against calling observer multiple times.
  if (got_response_)
    return;

  got_response_ = true;
  observer_->OnZipDone(success);
}

}  // namespace file_manager
