// 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 "net/tools/dump_cache/simple_cache_dumper.h"

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
#include "net/base/cache_type.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/disk_cache/disk_cache.h"
#include "net/tools/dump_cache/cache_dumper.h"

namespace net {

SimpleCacheDumper::SimpleCacheDumper(base::FilePath input_path,
                                     base::FilePath output_path)
    : state_(STATE_NONE),
      input_path_(input_path),
      output_path_(output_path),
      writer_(new DiskDumper(output_path)),
      cache_thread_(new base::Thread("CacheThead")),
      src_entry_(NULL),
      dst_entry_(NULL),
      io_callback_(base::Bind(&SimpleCacheDumper::OnIOComplete,
                              base::Unretained(this))),
      rv_(0) {
}

SimpleCacheDumper::~SimpleCacheDumper() {
}

int SimpleCacheDumper::Run() {
  base::MessageLoopForIO main_message_loop;

  LOG(INFO) << "Reading cache from: " << input_path_.value();
  LOG(INFO) << "Writing cache to: " << output_path_.value();

  if (!cache_thread_->StartWithOptions(
          base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) {
    LOG(ERROR) << "Unable to start thread";
    return ERR_UNEXPECTED;
  }
  state_ = STATE_CREATE_CACHE;
  int rv = DoLoop(OK);
  if (rv == ERR_IO_PENDING) {
    main_message_loop.Run();
    return rv_;
  }
  return rv;
}

int SimpleCacheDumper::DoLoop(int rv) {
  do {
    State state = state_;
    state_ = STATE_NONE;
    switch (state) {
      case STATE_CREATE_CACHE:
        CHECK_EQ(OK, rv);
        rv = DoCreateCache();
        break;
      case STATE_CREATE_CACHE_COMPLETE:
        rv = DoCreateCacheComplete(rv);
        break;
      case STATE_OPEN_ENTRY:
        CHECK_EQ(OK, rv);
        rv = DoOpenEntry();
        break;
      case STATE_OPEN_ENTRY_COMPLETE:
        rv = DoOpenEntryComplete(rv);
        break;
      case STATE_CREATE_ENTRY:
        CHECK_EQ(OK, rv);
        rv = DoCreateEntry();
        break;
      case STATE_CREATE_ENTRY_COMPLETE:
        rv = DoCreateEntryComplete(rv);
        break;
      case STATE_READ_HEADERS:
        CHECK_EQ(OK, rv);
        rv = DoReadHeaders();
        break;
      case STATE_READ_HEADERS_COMPLETE:
        rv = DoReadHeadersComplete(rv);
        break;
      case STATE_WRITE_HEADERS:
        CHECK_EQ(OK, rv);
        rv = DoWriteHeaders();
        break;
      case STATE_WRITE_HEADERS_COMPLETE:
        rv = DoWriteHeadersComplete(rv);
        break;
      case STATE_READ_BODY:
        CHECK_EQ(OK, rv);
        rv = DoReadBody();
        break;
      case STATE_READ_BODY_COMPLETE:
        rv = DoReadBodyComplete(rv);
        break;
      case STATE_WRITE_BODY:
        CHECK_EQ(OK, rv);
        rv = DoWriteBody();
        break;
      case STATE_WRITE_BODY_COMPLETE:
        rv = DoWriteBodyComplete(rv);
        break;
      default:
        NOTREACHED() << "state_: " << state_;
        break;
    }
  } while (state_ != STATE_NONE && rv != ERR_IO_PENDING);
  return rv;
}

int SimpleCacheDumper::DoCreateCache() {
  DCHECK(!cache_);
  state_ = STATE_CREATE_CACHE_COMPLETE;
  return disk_cache::CreateCacheBackend(
      DISK_CACHE, CACHE_BACKEND_DEFAULT, input_path_, 0, false,
      cache_thread_->task_runner(), NULL, &cache_, io_callback_);
}

int SimpleCacheDumper::DoCreateCacheComplete(int rv) {
  if (rv < 0)
    return rv;

  reinterpret_cast<disk_cache::BackendImpl*>(cache_.get())->SetUpgradeMode();
  reinterpret_cast<disk_cache::BackendImpl*>(cache_.get())->SetFlags(
      disk_cache::kNoRandom);

  state_ = STATE_OPEN_ENTRY;
  return OK;
}

int SimpleCacheDumper::DoOpenEntry() {
  DCHECK(!dst_entry_);
  DCHECK(!src_entry_);
  state_ = STATE_OPEN_ENTRY_COMPLETE;
  if (!iter_)
    iter_ = cache_->CreateIterator();
  return iter_->OpenNextEntry(&src_entry_, io_callback_);
}

int SimpleCacheDumper::DoOpenEntryComplete(int rv) {
  // ERR_FAILED indicates iteration finished.
  if (rv == ERR_FAILED)
    return OK;

  if (rv < 0)
    return rv;

  state_ = STATE_CREATE_ENTRY;
  return OK;
}

int SimpleCacheDumper::DoCreateEntry() {
  DCHECK(!dst_entry_);
  state_ = STATE_CREATE_ENTRY_COMPLETE;

  return writer_->CreateEntry(src_entry_->GetKey(), &dst_entry_,
                              io_callback_);
}

int SimpleCacheDumper::DoCreateEntryComplete(int rv) {
  if (rv < 0)
    return rv;

  state_ = STATE_READ_HEADERS;
  return OK;
}

int SimpleCacheDumper::DoReadHeaders() {
  state_ = STATE_READ_HEADERS_COMPLETE;
  int32 size = src_entry_->GetDataSize(0);
  buf_ = new IOBufferWithSize(size);
  return src_entry_->ReadData(0, 0, buf_.get(), size, io_callback_);
}

int SimpleCacheDumper::DoReadHeadersComplete(int rv) {
  if (rv < 0)
    return rv;

  state_ = STATE_WRITE_HEADERS;
  return OK;
}

int SimpleCacheDumper::DoWriteHeaders() {
  int rv = writer_->WriteEntry(
      dst_entry_, 0, 0, buf_.get(), buf_->size(), io_callback_);
  if (rv == 0)
    return ERR_FAILED;

  state_ = STATE_WRITE_HEADERS_COMPLETE;
  return OK;
}

int SimpleCacheDumper::DoWriteHeadersComplete(int rv) {
  if (rv < 0)
    return rv;

  state_ = STATE_READ_BODY;
  return OK;
}

int SimpleCacheDumper::DoReadBody() {
  state_ = STATE_READ_BODY_COMPLETE;
  int32 size = src_entry_->GetDataSize(1);
  // If the body is empty, we can neither read nor write it, so
  // just move to the next.
  if (size <= 0) {
    state_ = STATE_WRITE_BODY_COMPLETE;
    return OK;
  }
  buf_ = new IOBufferWithSize(size);
  return src_entry_->ReadData(1, 0, buf_.get(), size, io_callback_);
}

int SimpleCacheDumper::DoReadBodyComplete(int rv) {
  if (rv < 0)
    return rv;

  state_ = STATE_WRITE_BODY;
  return OK;
}

int SimpleCacheDumper::DoWriteBody() {
  int rv = writer_->WriteEntry(
      dst_entry_, 1, 0, buf_.get(), buf_->size(), io_callback_);
  if (rv == 0)
    return ERR_FAILED;

  state_ = STATE_WRITE_BODY_COMPLETE;
  return OK;
}

int SimpleCacheDumper::DoWriteBodyComplete(int rv) {
  if (rv < 0)
    return rv;

  src_entry_->Close();
  writer_->CloseEntry(dst_entry_, base::Time::Now(), base::Time::Now());
  src_entry_ = NULL;
  dst_entry_ = NULL;

  state_ = STATE_OPEN_ENTRY;
  return OK;
}

void SimpleCacheDumper::OnIOComplete(int rv) {
  rv = DoLoop(rv);

  if (rv != ERR_IO_PENDING) {
    rv_ = rv;
    cache_.reset();
    base::MessageLoop::current()->Quit();
  }
}

}  // namespace net
