/*
 * Copyright 2015 Google Inc. 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/virtual_file.h"
#include "cobalt/storage/virtual_file_system.h"

#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace storage {

class VirtualFileSystemTest : public testing::Test {
 protected:
  VirtualFileSystem vfs_;
};

TEST_F(VirtualFileSystemTest, WriteAndRead) {
  VirtualFile* file = vfs_.Open("file1.tmp");
  ASSERT_TRUE(file);
  EXPECT_EQ(0, file->Size());

  int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  file->Write(expected, sizeof(expected), 0);

  char out_data[128];
  int bytes = file->Read(out_data, sizeof(out_data), 0);
  EXPECT_EQ(bytes, sizeof(expected));
  EXPECT_EQ(0, memcmp(expected, out_data, sizeof(expected)));
}

TEST_F(VirtualFileSystemTest, ReadWriteOffsets) {
  VirtualFile* file = vfs_.Open("file1.tmp");
  ASSERT_TRUE(file);
  EXPECT_EQ(0, file->Size());

  char expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  file->Write(expected, sizeof(expected), 0);

  // Seek to position 4 and read bytes.
  char out_data[128];
  int bytes = file->Read(out_data, sizeof(out_data), 4);

  const int kDataSize = 6;
  EXPECT_EQ(kDataSize, bytes);
  EXPECT_EQ(0, memcmp(&expected[4], out_data, kDataSize));

  // Write some bytes into the middle
  file->Write(expected, 3, 3);
  char expected1[] = {0, 1, 2, 0, 1, 2, 6, 7, 8, 9};
  EXPECT_EQ(sizeof(expected1), file->Size());

  bytes = file->Read(out_data, sizeof(out_data), 0);
  EXPECT_EQ(0, memcmp(expected1, out_data, static_cast<size_t>(bytes)));

  // Try to read past the end.
  const int kOffsetPastEnd = 100000;
  bytes = file->Read(out_data, sizeof(out_data), kOffsetPastEnd);
  EXPECT_EQ(0, bytes);

  // Try to write past the end.
  file->Write(expected, sizeof(expected), kOffsetPastEnd);
  EXPECT_EQ(kOffsetPastEnd + sizeof(expected), file->Size());

  // Make sure the write past the end worked.
  bytes = file->Read(out_data, sizeof(out_data), kOffsetPastEnd);
  EXPECT_EQ(0, memcmp(expected, out_data, static_cast<size_t>(bytes)));
}

TEST_F(VirtualFileSystemTest, Open) {
  // Create a few files and write some data
  VirtualFile* file = vfs_.Open("file1.tmp");
  ASSERT_TRUE(file);
  EXPECT_EQ(0, file->Size());

  // Write a few bytes of random data.
  file->Write("test", 4, 0);
  EXPECT_EQ(4, file->Size());

  // Open a new file
  file = vfs_.Open("file2.tmp");
  ASSERT_TRUE(file);
  EXPECT_EQ(0, file->Size());

  // Try to reopen the existing file.
  file = vfs_.Open("file1.tmp");
  ASSERT_TRUE(file);
  EXPECT_EQ(4, file->Size());
}

TEST_F(VirtualFileSystemTest, SerializeDeserialize) {
  // Create a few files and write some data
  VirtualFile* file = vfs_.Open("file1.tmp");
  EXPECT_TRUE(file != NULL);
  const char data1[] = "abc";
  int data1_size = 3;
  file->Write(data1, data1_size, 0);

  file = vfs_.Open("file2.tmp");
  EXPECT_TRUE(file != NULL);
  const char data2[] = "defg";
  int data2_size = 4;
  file->Write(data2, data2_size, 0);

  // First perform a dry run to figure out how much space we need.
  int bytes = vfs_.Serialize(NULL, true /*dry run*/);
  scoped_array<uint8> buffer(new uint8[static_cast<size_t>(bytes)]);

  // Now serialize and deserialize
  vfs_.Serialize(buffer.get(), false /*dry run*/);

  // Deserialize the data into a new vfs
  VirtualFileSystem new_vfs;
  new_vfs.Deserialize(buffer.get(), bytes);

  // Make sure the new vfs contains all the expected data.
  char file_contents[VirtualFile::kMaxVfsPathname];
  file = new_vfs.Open("file1.tmp");
  EXPECT_TRUE(file != NULL);
  bytes = file->Read(file_contents, sizeof(file_contents), 0);
  EXPECT_EQ(data1_size, bytes);
  EXPECT_EQ(0, memcmp(file_contents, data1, static_cast<size_t>(bytes)));

  file = new_vfs.Open("file2.tmp");
  EXPECT_TRUE(file != NULL);
  bytes = file->Read(file_contents, sizeof(file_contents), 0);
  EXPECT_EQ(data2_size, bytes);
  EXPECT_EQ(0, memcmp(file_contents, data2, static_cast<size_t>(bytes)));
}

TEST_F(VirtualFileSystemTest, GetHeaderVersion) {
  VirtualFileSystem::SerializedHeader header;
  memset(&header, 0, sizeof(header));
  header.file_size = sizeof(header);

  COMPILE_ASSERT(sizeof(header.version) == sizeof("SAV0") - 1,
                 Invalid_header_version_size);
  memcpy(&header.version, "XYZW", sizeof(header.version));
  EXPECT_EQ(-1, VirtualFileSystem::GetHeaderVersion(header));
  memcpy(&header.version, "SAV0", sizeof(header.version));
  EXPECT_EQ(0, VirtualFileSystem::GetHeaderVersion(header));
  memcpy(&header.version, "SAV1", sizeof(header.version));
  EXPECT_EQ(1, VirtualFileSystem::GetHeaderVersion(header));
}

}  // namespace storage
}  // namespace cobalt
