// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/storage/savegame_thread.h"

#include "base/bind.h"
#include "base/debug/trace_event.h"
#include "base/message_loop.h"

// An arbitrary max size for the save game file so that, eg, a
// corrupt filesystem cannot cause us to allocate a fatally large
// memory buffer.
static size_t kMaxSaveGameSizeBytes = 4 * 1024 * 1024;

namespace cobalt {
namespace storage {

SavegameThread::SavegameThread(const Savegame::Options& options)
    : options_(options),
      initialized_(true /* manual reset */, false /* initially signalled */),
      thread_(new base::Thread("Savegame I/O")),
      num_consecutive_flush_failures_(0) {
  TRACE_EVENT0("cobalt::storage", __FUNCTION__);
  thread_->Start();
  thread_->message_loop()->PostTask(
      FROM_HERE, base::Bind(&SavegameThread::InitializeOnIOThread,
                            base::Unretained(this)));
}

SavegameThread::~SavegameThread() {
  TRACE_EVENT0("cobalt::storage", __FUNCTION__);
  thread_->message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&SavegameThread::ShutdownOnIOThread, base::Unretained(this)));

  // Wait for all tasks to finish.
  thread_.reset();
}

scoped_ptr<Savegame::ByteVector> SavegameThread::GetLoadedRawBytes() {
  TRACE_EVENT0("cobalt::storage", __FUNCTION__);
  initialized_.Wait();
  return loaded_raw_bytes_.Pass();
}

void SavegameThread::Flush(scoped_ptr<Savegame::ByteVector> raw_bytes_ptr,
                           const base::Closure& on_flush_complete) {
  TRACE_EVENT0("cobalt::storage", __FUNCTION__);
  DCHECK(raw_bytes_ptr->size() < kMaxSaveGameSizeBytes);
  if (raw_bytes_ptr->size() > kMaxSaveGameSizeBytes) {
    // We must not save a file larger than kMaxSaveGameSizeBytes
    // because we won't be able to reload it. Something must have
    // gone wrong, and it's far better to leave any existing readable
    // data that's persisted than it is to risk making it unreadable.
    if (!on_flush_complete.is_null()) {
      on_flush_complete.Run();
    }
    return;
  }
  thread_->message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&SavegameThread::FlushOnIOThread, base::Unretained(this),
                 base::Passed(&raw_bytes_ptr), on_flush_complete));
}

void SavegameThread::InitializeOnIOThread() {
  TRACE_EVENT0("cobalt::storage", __FUNCTION__);
  DCHECK_EQ(thread_->message_loop(), MessageLoop::current());

  // Create a savegame object on the storage I/O thread.
  savegame_ = options_.CreateSavegame();

  // Load the save data into our VFS, if it exists.
  loaded_raw_bytes_.reset(new Savegame::ByteVector());
  savegame_->Read(loaded_raw_bytes_.get(), kMaxSaveGameSizeBytes);

  // Signal storage is ready. Anyone waiting for the load will now be unblocked.
  initialized_.Signal();
}

void SavegameThread::ShutdownOnIOThread() {
  TRACE_EVENT0("cobalt::storage", __FUNCTION__);
  DCHECK_EQ(thread_->message_loop(), MessageLoop::current());
  // Ensure these objects are destroyed on the proper thread.
  savegame_.reset(NULL);
}

void SavegameThread::FlushOnIOThread(
    scoped_ptr<Savegame::ByteVector> raw_bytes_ptr,
    const base::Closure& on_flush_complete) {
  TRACE_EVENT0("cobalt::storage", __FUNCTION__);
  DCHECK_EQ(thread_->message_loop(), MessageLoop::current());
  if (raw_bytes_ptr->size() > 0) {
    bool ret = savegame_->Write(*raw_bytes_ptr);
    if (ret) {
      num_consecutive_flush_failures_ = 0;
    } else {
      DLOG(ERROR) << "Save failed.";
      const int kMaxConsecutiveFlushFailures = 2;
      DCHECK_LT(++num_consecutive_flush_failures_,
                kMaxConsecutiveFlushFailures);
    }
  }

  if (!on_flush_complete.is_null()) {
    on_flush_complete.Run();
  }
}

}  // namespace storage
}  // namespace cobalt
